home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / SNNSV32.ZIP / SNNSv3.2 / kernel / sources / kr_newpattern.c < prev    next >
C/C++ Source or Header  |  1994-04-25  |  82KB  |  2,794 lines

  1. /*****************************************************************************
  2.   FILE           : kr_newpattern.c
  3.   SHORTNAME      : newpattern
  4.   SNNS VERSION   : 3.2
  5.  
  6.   PURPOSE        : handling of new pattern files;
  7.   NOTES          :
  8.  
  9.   AUTHOR         : Michael Vogt
  10.   DATE           : 10.9.93
  11.  
  12.   CHANGED BY     : 
  13.   IDENTIFICATION : @(#)kr_newpattern.c    1.6 4/21/94
  14.   SCCS VERSION   : 1.6
  15.   LAST CHANGE    : 4/21/94
  16.  
  17.              Copyright (c) 1990-1994  SNNS Group, IPVR, Univ. Stuttgart, FRG
  18.  
  19. ******************************************************************************/
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <unistd.h>
  24. #include <string.h>
  25. #include <time.h>
  26. #include <sys/types.h>
  27. #include <sys/time.h>
  28.  
  29. #include "kr_typ.h"
  30. #include "glob_typ.h"
  31. #include "kr_mac.h"
  32.  
  33. #ifndef rand
  34. #include "random.h"      /*  Randomize Library Function Prototypes  */
  35. #endif
  36.  
  37. #include "kernel.h"
  38. #include "kr_const.h"
  39. #include "kr_pat_scan.h"
  40. #include "kr_pat_parse.h"
  41. #include "kr_newpattern.ph"
  42.  
  43. /*****************************************************************************
  44.  FUNCTIONS WHICH ARE CALLED BY THE KERNEL USER INTERFACE TO PERFORM
  45.  THE KERNEL INTERFACE OF THE NEW PATTERN MANAGEMENT
  46. ******************************************************************************/
  47.  
  48. /*****************************************************************************
  49.   FUNCTION : kr_npui_setCurrPatSet
  50.  
  51.   PURPOSE  : determines the number of the current pattern set (in
  52.              kernel terminology) numbering starts with 0
  53.   RETURNS  : kernel error code
  54.   NOTES    :
  55.  
  56.   UPDATE   : 
  57. ******************************************************************************/
  58. krui_err kr_npui_setCurrPatSet(int number)
  59. {
  60.     if (number<0 || number>=npui_number_pat_sets)
  61.     return KRERR_NP_NO_SUCH_PATTERN_SET;
  62.  
  63.     npui_curr_pat_set = number;
  64.     npui_curr_pattern = 1;
  65.     npui_train_defined = FALSE;
  66.     npui_show_defined = FALSE;
  67.     np_abs_count_valid = FALSE;
  68.     np_sub_pat_sizes_valid = FALSE;
  69.  
  70.     return KRERR_NO_ERROR;
  71. }
  72.  
  73. /*****************************************************************************
  74.   FUNCTION : kr_npui_deletePatSet
  75.  
  76.   PURPOSE  : deletes the specified pattern set from memory and
  77.              undefines the current pattern set, pattern, training
  78.          scheme and display scheme
  79.   RETURNS  : kernel error code
  80.   NOTES    :
  81.  
  82.   UPDATE   : 
  83. ******************************************************************************/
  84. krui_err kr_npui_deletePatSet(int number)
  85. {
  86.     int i;
  87.     int pat_set;
  88.  
  89.     if (number<0 || number>=npui_number_pat_sets)
  90.     return KRERR_NP_NO_SUCH_PATTERN_SET;
  91.  
  92.     pat_set = npui_pat_sets[number];
  93.  
  94.     for (i=number; i<npui_number_pat_sets-1; i++)
  95.     npui_pat_sets[i] = npui_pat_sets[i+1];
  96.     npui_number_pat_sets--;
  97.     npui_curr_pat_set = -1;
  98.     npui_curr_pattern = -1;
  99.     npui_train_defined = FALSE;
  100.     npui_show_defined = FALSE;
  101.     np_abs_count_valid = FALSE;
  102.     np_sub_pat_sizes_valid = FALSE;
  103.  
  104.     return kr_np_DeletePatternSet(pat_set);
  105. }
  106.  
  107. /*****************************************************************************
  108.   FUNCTION : kr_npui_GetPatInfo
  109.  
  110.   PURPOSE  : retrieves all available information concerning the
  111.              current pattern set and the current pattern which both
  112.          must be defined. The given parameter fields are filled
  113.          with the information.
  114.   RETURNS  : kernel error code
  115.   NOTES    :
  116.  
  117.   UPDATE   : 
  118. ******************************************************************************/
  119. krui_err kr_npui_GetPatInfo(pattern_set_info *set_info, 
  120.                             pattern_descriptor *pat_info)
  121. {
  122.     pattern_descriptor *int_pat_info;
  123.     krui_err err_code;
  124.  
  125.     if (npui_curr_pat_set == -1)
  126.     return KRERR_NP_NO_CURRENT_PATTERN_SET;
  127.  
  128.     if (npui_curr_pattern == -1)
  129.     return KRERR_NP_NO_CURRENT_PATTERN;
  130.  
  131.     err_code = kr_np_GetInfo(npui_pat_sets[npui_curr_pat_set],
  132.                  set_info);
  133.     if (err_code != KRERR_NO_ERROR)
  134.     return err_code;
  135.  
  136.     err_code = kr_np_GetDescriptor(npui_pat_sets[npui_curr_pat_set],
  137.                    npui_curr_pattern-1,
  138.                    &int_pat_info);
  139.     if (err_code != KRERR_NO_ERROR)
  140.     return err_code;
  141.  
  142.     *pat_info = *int_pat_info;
  143.  
  144.     return KRERR_NO_ERROR;
  145. }
  146.  
  147. /*****************************************************************************
  148.   FUNCTION : kr_npui_DefShowSubPat
  149.  
  150.   PURPOSE  : Define the display scheme:
  151.              Size and position of a sub pattern for the current
  152.              pattern in the current pattern set is defined. <insize>
  153.          is a pointer to an array of integer values which define
  154.          the dimensional sizes of the input sub pattern. <inpos>
  155.          is a pointer to an array of integer values which defines
  156.          the offset (position) of this sub pattern inside the
  157.          pattern. <outsize> and <outpos> are used to define the
  158.          respective output sub pattern 
  159.   RETURNS  : kernel error code
  160.   NOTES    :
  161.  
  162.   UPDATE   : 
  163. ******************************************************************************/
  164. krui_err kr_npui_DefShowSubPat(int *insize, int *outsize, 
  165.                                int *inpos, int *outpos)
  166. {
  167.     krui_err err_code;
  168.     pattern_descriptor *pattern;
  169.     int i;
  170.  
  171.     npui_show_defined = FALSE;
  172.  
  173.     if (npui_curr_pat_set == -1)
  174.     return KRERR_NP_NO_CURRENT_PATTERN_SET;
  175.  
  176.     if (npui_curr_pattern == -1)
  177.     return KRERR_NP_NO_CURRENT_PATTERN;
  178.  
  179.     err_code = kr_np_GetDescriptor(npui_pat_sets[npui_curr_pat_set],
  180.                    npui_curr_pattern-1,
  181.                    &pattern);
  182.  
  183.     if (err_code != KRERR_NO_ERROR)
  184.     return err_code;
  185.  
  186.     for (i=0; i<pattern->input_dim; i++)
  187.     {
  188.     if ((pattern->input_dim_sizes)[i] < insize[i] + inpos[i] - 1)
  189.         err_code = KRERR_NP_DIMENSION;
  190.     }
  191.     for (i=0; i<pattern->output_dim; i++)
  192.     {
  193.     if ((pattern->output_dim_sizes)[i] < outsize[i] + outpos[i] - 1)
  194.         err_code = KRERR_NP_DIMENSION;
  195.     }
  196.  
  197.     if (err_code != KRERR_NO_ERROR)
  198.     return err_code;
  199.  
  200.     memcpy(npui_insize, insize, MAX_NO_OF_VAR_DIM * sizeof(int));
  201.     memcpy(npui_outsize, outsize, MAX_NO_OF_VAR_DIM * sizeof(int));
  202.     memcpy(npui_inpos, inpos, MAX_NO_OF_VAR_DIM * sizeof(int));
  203.     memcpy(npui_outpos, outpos, MAX_NO_OF_VAR_DIM * sizeof(int));
  204.     for (i=0; i<MAX_NO_OF_VAR_DIM; i++)
  205.     {
  206.     npui_inpos[i]--;
  207.     npui_outpos[i]--;
  208.     }
  209.  
  210.     npui_show_defined = TRUE;
  211.  
  212.     return KRERR_NO_ERROR;
  213. }
  214.  
  215. /*****************************************************************************
  216.   FUNCTION : kr_npui_DefTrainSubPat
  217.  
  218.   PURPOSE  : Define the training scheme:
  219.              Size and step size of sub pattern for the current pattern
  220.              in the current pattern set is defined for training and
  221.          testing. <insize> is a pointer to an array of integer
  222.          values which define the dimensional sizes of the input sub
  223.          pattern. <instep> is a pointer to an array of integer
  224.          values which defines the step size which is used to move
  225.          the sub pattern over the pattern.
  226.              <outsize> and <outpos> are used to define the respective
  227.          output sub pattern. 
  228.              <max_n_pos> (if not NULL) returns the number of valid
  229.          input sub pattern positions for the current pattern and
  230.          the given training scheme.
  231.  
  232.   RETURNS  : kernel error code
  233.   NOTES    :
  234.  
  235.   UPDATE   : 
  236. ******************************************************************************/
  237. krui_err kr_npui_DefTrainSubPat(int *insize, int *outsize, 
  238.                                 int *instep, int *outstep, int *max_n_pos)
  239. {
  240.     krui_err err_code;
  241.     int n;
  242.     pattern_descriptor *p;
  243.  
  244.     npui_train_defined = FALSE;
  245.     np_abs_count_valid = FALSE;
  246.     np_sub_pat_sizes_valid = FALSE;
  247.  
  248.     if (npui_curr_pat_set == -1)
  249.     return KRERR_NP_NO_CURRENT_PATTERN_SET;
  250.  
  251.     if (npui_curr_pattern == -1)
  252.     return KRERR_NP_NO_CURRENT_PATTERN;
  253.  
  254.     memcpy(npui_insize, insize, MAX_NO_OF_VAR_DIM * sizeof(int));
  255.     memcpy(npui_outsize, outsize, MAX_NO_OF_VAR_DIM * sizeof(int));
  256.     memcpy(npui_instep, instep, MAX_NO_OF_VAR_DIM * sizeof(int));
  257.     memcpy(npui_outstep, outstep, MAX_NO_OF_VAR_DIM * sizeof(int));
  258.  
  259.     err_code = 
  260.     kr_np_DefineSubPatternOrdering(npui_pat_sets[npui_curr_pat_set],
  261.                        TRUE, npui_insize, npui_instep);
  262.     if (err_code != KRERR_NO_ERROR)
  263.     return err_code;
  264.  
  265.     err_code = 
  266.     kr_np_DefineSubPatternOrdering(npui_pat_sets[npui_curr_pat_set],
  267.                        FALSE, npui_outsize,
  268.                        npui_outstep);
  269.     if (err_code != KRERR_NO_ERROR)
  270.     return err_code;
  271.  
  272.     npui_train_defined = TRUE;
  273.  
  274.     if (max_n_pos != (int *) NULL)
  275.     {
  276.     err_code = kr_np_GetDescriptor(npui_pat_sets[npui_curr_pat_set],
  277.                        npui_curr_pattern-1, &p);
  278.     if (err_code != KRERR_NO_ERROR)
  279.         return err_code;
  280.  
  281.     if (!kr_np_gen_sub_pos(p->input_dim, &n, p->input_dim_sizes, 
  282.                    npui_insize, npui_instep, (int *) NULL, 
  283.                    TRUE))
  284.         return KRERR_NP_DIMENSION;
  285.     *max_n_pos = n;
  286.     }
  287.  
  288.     return KRERR_NO_ERROR;
  289. }
  290.  
  291.  
  292. /*****************************************************************************
  293.   FUNCTION : kr_npui_AlignSubPat
  294.  
  295.   PURPOSE  : Align the position of a sub pattern:
  296.              Using the current training scheme and the current pattern
  297.          of the current pattern set, the given position of an
  298.          input sub pattern <inpos> and the given position of the
  299.          corresponding output sub pattern <outpos> is aligned to fit
  300.          the currently defined training scheme.
  301.          E.g. if the training scheme defines a step width of 5 for
  302.          a specific dimension, only the positions 0, 5, 10, 15 ...
  303.          are valid positions for a sub pattern.
  304.          The position of each dimension is aligned independently
  305.          from all other dimensions by moving to the next valid
  306.          position which is lower or equal to the given position.
  307.              <no> (if not NULL) returns the number of the sub pattern
  308.          which corresponds to the new aligned position which is
  309.          returned in place (<inpos> <outpos>).
  310.  
  311.   RETURNS  : kernel error code
  312.   NOTES    :
  313.  
  314.   UPDATE   : 
  315. ******************************************************************************/
  316. krui_err kr_npui_AlignSubPat(int *inpos, int *outpos, int *no)
  317. {
  318.     krui_err err_code;
  319.     pattern_descriptor *p;
  320.     int pos;
  321.     int i;
  322.  
  323.     if (npui_curr_pat_set == -1)
  324.     return KRERR_NP_NO_CURRENT_PATTERN_SET;
  325.  
  326.     if (npui_curr_pattern == -1)
  327.     return KRERR_NP_NO_CURRENT_PATTERN;
  328.  
  329.     if (npui_train_defined == FALSE)
  330.     return KRERR_NP_NO_TRAIN_SCHEME;
  331.  
  332.     err_code = kr_np_GetDescriptor(npui_pat_sets[npui_curr_pat_set],
  333.                    npui_curr_pattern-1, &p);
  334.     if (err_code != KRERR_NO_ERROR)
  335.     return err_code;
  336.  
  337.     /* enumeration starts with 0, not with 1 */
  338.     for (i=0; i< p->input_dim; i++)
  339.     inpos[i] -= 1;
  340.  
  341.     /* align the position of the input sub pattern */
  342.     if (!kr_np_align_sub_pos(p->input_dim, &pos, 
  343.                  p->input_dim_sizes, npui_insize, 
  344.                  npui_instep, inpos))
  345.     {
  346.     for (i=0; i< p->input_dim; i++)
  347.         inpos[i] = 1;
  348.     return KRERR_NP_DIMENSION;
  349.     }
  350.  
  351.     /* now enumeration starts with 1 again */
  352.     for (i=0; i< p->input_dim; i++)
  353.     inpos[i] += 1;
  354.  
  355.     /* find the output sub pattern which is related to the aligned */
  356.     /* input sub pattern */
  357.     if (!kr_np_gen_sub_pos(p->output_dim, &pos, 
  358.                p->output_dim_sizes, npui_outsize, 
  359.                npui_outstep, outpos, FALSE))
  360.     {
  361.     for (i=0; i< p->output_dim; i++)
  362.         outpos[i] = 1;
  363.     return KRERR_NP_DIMENSION;
  364.     }
  365.  
  366.     /* now enumeration starts with 1 again */
  367.     for (i=0; i< p->output_dim; i++)
  368.     outpos[i] += 1;
  369.  
  370.     /* return the absolute position */
  371.     *no = pos+1;
  372.  
  373.     return KRERR_NO_ERROR;
  374. }
  375.  
  376. /*****************************************************************************
  377.   FUNCTION : kr_npui_allocNewPatternSet
  378.  
  379.   PURPOSE : Allocate an (additional) empty pattern set: A new pattern
  380.   set is allocated if the maximum number of loaded pattern sets
  381.   (NO_OF_PAT_SETS) is not exceeded. The corresponding pattern set
  382.   handle is returned in <set_no>.  The new allocated pattern set
  383.   becomes the current set.  There is no current pattern defined.
  384.   Training scheme and display scheme both become undefined.
  385.  
  386.   NOTES    : 
  387.  
  388.   RETURNS  : 
  389.   UPDATE   : 
  390. ******************************************************************************/
  391. krui_err kr_npui_allocNewPatternSet(int *set_no)
  392. {
  393.     int pat_set;
  394.     krui_err err_code;
  395.  
  396.     if (npui_number_pat_sets >= NO_OF_PAT_SETS)
  397.     return KRERR_NP_NO_MORE_ENTRIES;
  398.  
  399.     /* allocate pattern set with zero pattern */
  400.     err_code = kr_np_AllocatePatternSet(&pat_set, 0);
  401.     if (err_code == KRERR_NO_ERROR)
  402.     {
  403.     npui_curr_pat_set = npui_number_pat_sets;
  404.     npui_number_pat_sets++;
  405.     npui_curr_pattern = -1;
  406.     npui_pat_sets[npui_curr_pat_set] = pat_set;
  407.     *set_no = npui_curr_pat_set;
  408.     npui_train_defined = FALSE;
  409.     npui_show_defined = FALSE;
  410.     np_abs_count_valid = FALSE;
  411.     np_sub_pat_sizes_valid = FALSE;
  412.     }
  413.  
  414.     return err_code;
  415. }
  416.  
  417. /*****************************************************************************
  418.   FUNCTION : kr_npui_loadNewPatterns
  419.  
  420.   PURPOSE  : Load an (additional) pattern file:
  421.              The file with name <filename> is loaded into memory if
  422.          existent and if the maximum number of loaded pattern sets
  423.          (NO_OF_PAT_SETS) is not exceeded. The corresponding
  424.          pattern set handle is returned in <set_no>.
  425.  
  426.          The new loaded pattern set becomes the current set. The
  427.          first pattern inside this set becomes the current
  428.          pattern. Training scheme and display scheme both become
  429.          undefined.
  430.  
  431.   RETURNS  : kernel error code
  432.   NOTES    :
  433.  
  434.   UPDATE   : 
  435. ******************************************************************************/
  436. krui_err kr_npui_loadNewPatterns(char *filename, int *set_no)
  437. {
  438.     FILE *infile;
  439.     int pat_set;
  440.     int read_from_pipe = 0;
  441.     char *buf;
  442.     krui_err err_code;
  443.  
  444.     if (npui_number_pat_sets >= NO_OF_PAT_SETS)
  445.     return KRERR_NP_NO_MORE_ENTRIES;
  446.  
  447.     if (access(filename, F_OK) != 0)
  448.     return KRERR_FILE_OPEN;
  449.     if (strcmp(&filename[strlen(filename)-2], ".Z") == 0)
  450.     {
  451.     buf = (char *) malloc(strlen(filename)+strlen("zcat ")+1);
  452.     if (buf == (char *) NULL)
  453.         return KRERR_INSUFFICIENT_MEM;
  454.     sprintf(buf, "zcat %s", filename);
  455.     infile = popen(buf,"r");
  456.     read_from_pipe = 1;
  457.     }
  458.     else
  459.     infile = fopen(filename, "r");
  460.     if (infile == (FILE *) NULL)
  461.     return KRERR_FILE_OPEN;
  462.  
  463.     err_code = kr_np_LoadPatternFile(infile, &pat_set);
  464.     if (err_code == KRERR_NO_ERROR)
  465.     {
  466.     npui_curr_pat_set = npui_number_pat_sets;
  467.     npui_number_pat_sets++;
  468.     npui_curr_pattern = 1;
  469.     npui_pat_sets[npui_curr_pat_set] = pat_set;
  470.     *set_no = npui_curr_pat_set;
  471.     npui_train_defined = FALSE;
  472.     npui_show_defined = FALSE;
  473.     np_abs_count_valid = FALSE;
  474.     np_sub_pat_sizes_valid = FALSE;
  475.     }
  476.  
  477.     if (read_from_pipe)
  478.     {
  479.     pclose(infile);
  480.     free(buf);
  481.     }
  482.     else
  483.     fclose(infile);
  484.  
  485.     return err_code;
  486. }
  487.  
  488. /*****************************************************************************
  489.   FUNCTION : kr_npui_saveNewPatterns
  490.  
  491.   PURPOSE  : The given pattern set <set_no> is written to file
  492.              <filename> in new style format. No side effects.
  493.  
  494.   RETURNS  : kernel error code
  495.   NOTES    :
  496.  
  497.   UPDATE   : 
  498. ******************************************************************************/
  499. krui_err kr_npui_saveNewPatterns(char *filename, int set_no)
  500. {
  501.     FILE *outfile;
  502.     krui_err err_code;
  503.  
  504.     if (set_no<0 || set_no>=npui_number_pat_sets)
  505.     return KRERR_NP_NO_SUCH_PATTERN_SET;
  506.  
  507.     outfile = fopen(filename, "w");
  508.     if (outfile == (FILE *) NULL)
  509.     return KRERR_FILE_OPEN;
  510.  
  511.     err_code = kr_np_SavePatternFile(outfile, npui_pat_sets[set_no]);
  512.  
  513.     fclose(outfile);
  514.  
  515.     return err_code;
  516. }
  517.  
  518. /*****************************************************************************
  519.   FUNCTION : kr_npui_GetShapeOfSubPat
  520.  
  521.   PURPOSE  : Get the shape of a sub pattern which is specified by a
  522.              number:
  523.              After kr_npui_DefTrainSubPat has been called for the
  524.          current pattern set and a current pattern is defined,
  525.          this function retrieves the <n_pos>th valid sub pattern
  526.          pair which matches the defined training scheme. Size and
  527.          position of the sub pattern pair is returned in <insize>
  528.          <inpos> <outsize> and <outpos> which are all pointer to
  529.          integer arrays.
  530.  
  531.   RETURNS  : kernel error code
  532.   NOTES    :
  533.  
  534.   UPDATE   : 
  535. ******************************************************************************/
  536. krui_err kr_npui_GetShapeOfSubPat(int *insize, int *outsize, 
  537.                                 int *inpos, int *outpos, int n_pos)
  538. {
  539.     int sp[MAX_NO_OF_VAR_DIM];
  540.     pattern_descriptor *p;
  541.     krui_err err_code;
  542.     int n;
  543.     int i;
  544.  
  545.     if (npui_curr_pat_set == -1)
  546.     return KRERR_NP_NO_CURRENT_PATTERN_SET;
  547.  
  548.     if (npui_curr_pattern == -1)
  549.     return KRERR_NP_NO_CURRENT_PATTERN;
  550.  
  551.     if (!npui_train_defined)
  552.     return KRERR_NP_NO_TRAIN_SCHEME;
  553.  
  554.     err_code = kr_np_GetDescriptor(npui_pat_sets[npui_curr_pat_set],
  555.                    npui_curr_pattern-1, &p);
  556.     if (err_code != KRERR_NO_ERROR)
  557.     return err_code;
  558.  
  559.     n = n_pos-1;
  560.     if (!kr_np_gen_sub_pos(p->input_dim, &n, p->input_dim_sizes, 
  561.                npui_insize, npui_instep, sp, FALSE))
  562.     return KRERR_NP_NO_SUCH_PATTERN;
  563.     
  564.     memcpy((char *) inpos, (char *) sp, p->input_dim * sizeof(int));
  565.     for (i=0; i<p->input_dim; i++)
  566.     inpos[i]++;
  567.  
  568.     if (!kr_np_gen_sub_pos(p->output_dim, &n, p->output_dim_sizes, 
  569.                npui_outsize, npui_outstep, sp, FALSE))
  570.     return KRERR_NP_NO_SUCH_PATTERN;
  571.  
  572.     memcpy((char *) outpos, (char *) sp, p->output_dim *sizeof(int));
  573.     for (i=0; i<p->output_dim; i++)
  574.     outpos[i]++;
  575.  
  576.     memcpy((char *) insize, (char *) npui_insize, p->input_dim *sizeof(int));
  577.     memcpy((char *) outsize, (char *) npui_outsize, p->input_dim *sizeof(int));
  578.  
  579.     return KRERR_NO_ERROR;
  580. }
  581.  
  582. /*****************************************************************************
  583.  FUNCTIONS WHICH ARE CALLED BY OTHER KERNEL FUNCTIONS LIKE TRAINING
  584.  AND INITIALIZATION FUNCTIONS:
  585. ******************************************************************************/
  586.  
  587. /*****************************************************************************
  588.   FUNCTION : kr_np_pattern
  589.  
  590.   PURPOSE  : multiple pattern handling functions depending on mode and mode1
  591.   RETURNS  : result, depending on operation or kernel error code
  592.   NOTES    : KernelErrorCode is set to the valid kernel error code
  593.  
  594.   UPDATE   : 
  595. ******************************************************************************/
  596. int  kr_np_pattern(int mode ,int mode1 ,int pattern_no)
  597. {
  598.     int return_code;
  599.     int new_pattern;
  600.     pattern_set_info info;
  601.  
  602.     return_code = (int) (KernelErrorCode = KRERR_NO_ERROR);
  603.  
  604.     if (npui_curr_pat_set == -1)
  605.     {
  606.     KernelErrorCode = KRERR_NP_NO_CURRENT_PATTERN_SET;
  607.     return (int) KernelErrorCode;
  608.     }
  609.  
  610.     /* for some modes, test current pattern definition */ 
  611.     switch (mode)
  612.     {
  613.       case  PATTERN_GET:    /*  returns the current pattern  */
  614.       case  PATTERN_DELETE:    /*  delete the current pattern pair  */
  615.       case  PATTERN_MODIFY:    /*  modify the current pattern pair  */
  616.       case  PATTERN_SHOW:    /*  show pattern  */
  617.     if (npui_curr_pattern == -1 && mode != PATTERN_SET)
  618.     {
  619.         KernelErrorCode = KRERR_NP_NO_CURRENT_PATTERN;
  620.         return (int) KernelErrorCode;
  621.     }
  622.       default:
  623.     break;
  624.     }
  625.  
  626.     switch (mode)
  627.     {
  628.       case  PATTERN_SET:    /*  set the current pattern  */
  629.     if (pattern_no < 1 || pattern_no >
  630.     np_info[npui_pat_sets[npui_curr_pat_set]].number_of_pattern)
  631.     {
  632.         return_code = (int) (KernelErrorCode = KRERR_PATTERN_NO);
  633.         npui_curr_pattern = -1;
  634.     }
  635.     else
  636.         npui_curr_pattern = pattern_no;
  637.     break;
  638.  
  639.       case  PATTERN_GET:    /*  returns the current pattern  */
  640.     return_code = npui_curr_pattern;
  641.     break;
  642.  
  643.       case  PATTERN_DELETE:    /*  delete the current pattern pair  */
  644.     return_code = kr_np_DeletePattern(npui_pat_sets[npui_curr_pat_set],
  645.                       npui_curr_pattern-1);
  646.     npui_curr_pattern = -1;
  647.     break;
  648.  
  649.       case  PATTERN_MODIFY:    /*  modify the current pattern pair  */
  650.     return_code = (int) (KernelErrorCode = kr_np_modifyPattern());
  651.     break;
  652.  
  653.       case  PATTERN_SHOW:    /*  show pattern  */
  654.     return_code = (int) (KernelErrorCode = kr_np_showPatternSTD(mode1));
  655.     break;
  656.  
  657.       case  PATTERN_NEW:    /*  new pattern  */
  658.     /* before creating a new pattern, first ensure that new pattern */
  659.     /* fits into existing set */
  660.     return_code = kr_np_GetInfo(npui_pat_sets[npui_curr_pat_set], &info);
  661.     if (return_code != KRERR_NO_ERROR)
  662.         break;
  663.     (void) kr_IOCheck();
  664.     if (NoOfInputUnits == 0)
  665.     {
  666.         return_code = KernelErrorCode = KRERR_NO_INPUT_UNITS;
  667.         break;
  668.     }
  669.  
  670.     if (info.number_of_pattern > 0)
  671.     {
  672.         if (info.in_number_of_dims != 0 || 
  673.         info.out_number_of_dims != 0 ||
  674.         info.in_fixsize != NoOfInputUnits || 
  675.          info.out_fixsize != NoOfOutputUnits)
  676.         {
  677.         /* creation of variable sized patterns is not possible */
  678.         /* also the new pattern must be of equal size compared to */
  679.         /* existing pattern */
  680.         return_code = KRERR_NP_INCOMPATIBLE_NEW;
  681.         break;
  682.         }
  683.     }
  684.  
  685.     return_code = KernelErrorCode =
  686.         kr_np_AddPattern(npui_pat_sets[npui_curr_pat_set], &new_pattern);
  687.     if (return_code != KRERR_NO_ERROR)
  688.         break;
  689.  
  690.     npui_curr_pattern = new_pattern + 1;
  691.     return_code = (int) (KernelErrorCode = kr_np_modifyPattern());
  692.     if (return_code != KRERR_NO_ERROR)
  693.     {
  694.         (void) kr_np_DeletePattern(npui_pat_sets[npui_curr_pat_set],
  695.                        npui_curr_pattern-1);
  696.         npui_curr_pattern = -1;
  697.     }
  698.     break;
  699.  
  700.       case  PATTERN_DELETE_ALL:    /*  delete all pattern  */
  701.     break;
  702.  
  703.       case  PATTERN_SHUFFLE_ON:    /*  shuffle pattern  */
  704.     npui_shuffle_pattern = TRUE;
  705.     break;
  706.  
  707.       case  PATTERN_SHUFFLE_OFF: /*  shuffle pattern off */
  708.     npui_shuffle_pattern = FALSE;
  709.     break;
  710.  
  711.       case  PATTERN_SET_NUMBER:
  712.     break;
  713.  
  714.       case  PATTERN_GET_NUMBER:
  715.     return_code = 
  716.         np_info[npui_pat_sets[npui_curr_pat_set]].number_of_pattern;
  717.     break;
  718.     
  719.       case  PATTERN_SUB_SHUFFLE_ON:
  720.     npui_shuffle_sub_pattern = TRUE;
  721.     break;
  722.  
  723.       case  PATTERN_SUB_SHUFFLE_OFF:
  724.     npui_shuffle_sub_pattern = FALSE;
  725.     break;
  726.  
  727.       case GET_SHUFFLE_FLAG:
  728.     return_code = npui_shuffle_pattern;
  729.     break;
  730.  
  731.       case GET_SUB_SHUFFLE_FLAG:
  732.     return_code = npui_shuffle_sub_pattern;
  733.     break;
  734.  
  735.       default:
  736.     KernelErrorCode = KRERR_PARAMETERS;
  737.     }
  738.  
  739.     return return_code;
  740. }
  741.  
  742. /*****************************************************************************
  743.   FUNCTION : kr_initSubPatternOrder
  744.  
  745.   PURPOSE  : The sub pattern ordering for the current pattern set is
  746.              reset for the next training or initialization run. During
  747.          this run all sub patterns from pattern <start> up to
  748.          pattern <end> are generated according to current shuffle
  749.          flags for patterns and sub patterns.  
  750.              kr_getSubPatByOrder is to be called to get the next sub
  751.          pattern number during the run (see below) 
  752.  
  753.   RETURNS  : kernel error code
  754.   NOTES    :
  755.  
  756.   UPDATE   : 
  757. ******************************************************************************/
  758. krui_err kr_initSubPatternOrder(int start, int end)
  759. {
  760.     int pat_set;
  761.     int n_sub;
  762.  
  763.     if (!npui_train_defined)
  764.     return KRERR_NP_NO_TRAIN_SCHEME;
  765.  
  766.     pat_set = npui_pat_sets[npui_curr_pat_set];
  767.     if (!kr_np_allocate_pat_train_entries(np_info[pat_set].number_of_pattern))
  768.     return KRERR_INSUFFICIENT_MEM;
  769.  
  770.     if (npui_shuffle_pattern && npui_shuffle_sub_pattern)
  771.     {
  772.     np_random_train_number = kr_TotalNoOfSubPatPairs();
  773.     np_next_train_random = 0;
  774.  
  775.     return KRERR_NO_ERROR;
  776.     }
  777.  
  778.     kr_np_order_pat_entries(start, end);
  779.     np_next_train_pat = 0;
  780.  
  781.     np_current_pattern = 
  782.     &(np_pat_sets[pat_set][np_pat_train_order[0]]);
  783.     
  784.     kr_np_gen_sub_pos(np_current_pattern -> input_dim, &n_sub,
  785.               np_current_pattern -> input_dim_sizes, np_t_insize, 
  786.               np_t_instep, NULL, TRUE);
  787.  
  788.     if (!kr_np_allocate_sub_pat_train_entries(n_sub))
  789.     return KRERR_INSUFFICIENT_MEM;
  790.  
  791.     kr_np_order_sub_pat_entries(0, n_sub-1);
  792.     np_next_train_sub_pat = 0;
  793.  
  794.     return KRERR_NO_ERROR;
  795. }
  796.  
  797. /*****************************************************************************
  798.   FUNCTION : kr_getSubPatternByOrder
  799.  
  800.   PURPOSE : According to the last call to kr_initSubPatternOrder, the
  801.   last call to this function and the shuffle flags, the next position
  802.   of pattern and sub pattern is determined. This numbers are returned
  803.   in <pattern> and <sub> (beginning with 0). 
  804.  
  805.   RETURNS : If there are no more sub pattern avaliable the return
  806.   value is FALSE, otherwise TRUE.
  807.   NOTES    :
  808.  
  809.   UPDATE   : 
  810. ******************************************************************************/
  811. bool kr_getSubPatternByOrder(int *pattern, int *sub)
  812. {
  813.     int n_sub;
  814.  
  815.     if (npui_shuffle_pattern && npui_shuffle_sub_pattern)
  816.     {
  817.     if (np_next_train_random == -1)
  818.         return FALSE;
  819.  
  820.     if (++np_next_train_random >= np_random_train_number)
  821.         np_next_train_random = -1;
  822.  
  823.     return (kr_getSubPatternByNo(pattern, sub, 
  824.                      lrand48() % np_random_train_number));
  825.     }
  826.  
  827.     if (np_next_train_pat == -1)
  828.     return FALSE;
  829.  
  830.     *pattern = np_pat_train_order[np_next_train_pat];
  831.     *sub = np_sub_pat_train_order[np_next_train_sub_pat];
  832.  
  833.     np_next_train_sub_pat++;
  834.     if (np_next_train_sub_pat >= np_sub_pat_train_number)
  835.     {
  836.     np_next_train_pat++;
  837.     if (np_next_train_pat >= np_pat_train_number)
  838.     {
  839.         np_next_train_pat = -1;
  840.         return TRUE;
  841.     }
  842.  
  843.     np_current_pattern = 
  844.         &(np_pat_sets[npui_pat_sets[npui_curr_pat_set]]
  845.                      [np_pat_train_order[np_next_train_pat]]);
  846.     
  847.     kr_np_gen_sub_pos(np_current_pattern -> input_dim, &n_sub,
  848.               np_current_pattern -> input_dim_sizes, np_t_insize, 
  849.               np_t_instep, NULL, TRUE);
  850.  
  851.     if (!kr_np_allocate_sub_pat_train_entries(n_sub))
  852.     {
  853.         KernelErrorCode = KRERR_INSUFFICIENT_MEM;
  854.         return FALSE;
  855.     }
  856.  
  857.     kr_np_order_sub_pat_entries(0, n_sub-1);
  858.     np_next_train_sub_pat = 0;
  859.     }
  860.  
  861.     return TRUE;
  862. }
  863.  
  864. /*****************************************************************************
  865.   FUNCTION : kr_getSubPatternByNo
  866.  
  867.   PURPOSE : According to the current pattern set, the position of the
  868.   <n>th sub pattern is determined and returned in <pattern> (the
  869.   pattern which includes the subpattern) and <sub> (the sub pattern
  870.   inside the pattern) (beginning with 0).  
  871.   This function does not effect the ordering of the function
  872.   kr_getSubPatByOrder. <n> ranges from 0 to kr_TotalNoOfSubPatPairs()-1.
  873.  
  874.   RETURNS : If the sub pattern is available, TRUE is returned,
  875.   otherwise FALSE.
  876.  
  877.   NOTES    :
  878.  
  879.   UPDATE   : 
  880. ******************************************************************************/
  881. bool kr_getSubPatternByNo(int *pattern, int *sub, int n)
  882. {
  883.     register int ts;
  884.     register int tp;
  885.     register int low, high, mid;
  886.  
  887.     ts = kr_TotalNoOfSubPatPairs();
  888.     if (n<0 || n>=ts)
  889.     return FALSE;
  890.  
  891.     tp = np_info[npui_pat_sets[npui_curr_pat_set]].number_of_pattern;
  892.  
  893.     if (tp == 1)
  894.     /* only one pattern present, sub pattern must be here */
  895.     high = 0;
  896.     else
  897.     {
  898.     /* more than one pattern present.... */
  899.     /* first try to find the right position by a direct jump */
  900.     high = (n*tp)/ts;
  901.  
  902.     if (np_abs_count[high] <= n || (high != 0 && np_abs_count[high-1] > n))
  903.     {
  904.         /* direct jump was not sucessfull, now perform binary search */
  905.         low = 0;
  906.         high = tp-1;
  907.         while (low < high)
  908.         {
  909.         mid = (high+low)/2;
  910.         if (np_abs_count[mid] > n)
  911.             high = mid;
  912.         else
  913.             low = mid+1;
  914.         }
  915.     }
  916.     }
  917.  
  918.     /* now high gives the index of the pattern where the sub pattern is in */
  919.     *pattern = high;
  920.  
  921.     /* calculate the position of the sub pattern inside the found pattern */
  922.     if (high != 0)
  923.     *sub = n - np_abs_count[high-1];
  924.     else
  925.     *sub = n;
  926.  
  927.     return TRUE;
  928. }
  929.  
  930. /*****************************************************************************
  931.   FUNCTION : kr_TotalNoOfSubPatPairs
  932.  
  933.   PURPOSE : This function returns the total number of available sub
  934.   patterns for the current pattern set or 0 if no pattern set is
  935.   defined.  The result is the sum of the numbers of subpattern for all
  936.   patterns in the current set.
  937.  
  938.   RETURNS  : number of sub pattern or 0
  939.   NOTES    :
  940.  
  941.   UPDATE   : 
  942. ******************************************************************************/
  943. int kr_TotalNoOfSubPatPairs(void)
  944. {
  945.     int n;
  946.     int i;
  947.     int sum;
  948.     int n_sub;
  949.     pattern_descriptor *pat;
  950.  
  951.     if (np_abs_count_valid)
  952.     return np_abs_count_No;
  953.  
  954.     if (npui_curr_pat_set == -1)
  955.     return 0;
  956.  
  957.     n = np_info[npui_pat_sets[npui_curr_pat_set]].number_of_pattern;
  958.  
  959.     if (n > np_abs_count_size)
  960.     {
  961.     if (np_abs_count != (int *) NULL)
  962.         free(np_abs_count);
  963.     np_abs_count_size = 0;
  964.     np_abs_count = (int *) malloc(n * sizeof(int));
  965.     if (np_abs_count == (int *) NULL && n != 0)
  966.         return 0;
  967.     np_abs_count_size = n;
  968.     }
  969.  
  970.     pat = np_pat_sets[npui_pat_sets[npui_curr_pat_set]];
  971.     sum = 0;
  972.     for (i=0; i<n; i++)
  973.     {
  974.     kr_np_gen_sub_pos(pat -> input_dim, &n_sub, 
  975.               pat -> input_dim_sizes, np_t_insize,
  976.               np_t_instep, NULL, TRUE);
  977.     sum += n_sub;
  978.     np_abs_count[i] = sum;
  979.     pat++;
  980.     }
  981.     np_abs_count_No = sum;
  982.     np_abs_count_valid = TRUE;
  983.  
  984.     return np_abs_count_No;
  985. }
  986.  
  987. /*****************************************************************************
  988.   FUNCTION : kr_NoOfSubPatPairs
  989.  
  990.   PURPOSE  : This function returns the number of available sub patterns
  991.   for the pattern <pattern> of the current pattern set or 0 if this
  992.   pattern is not defined.
  993.  
  994.   RETURNS  : 
  995.   NOTES    :
  996.  
  997.   UPDATE   : 
  998. ******************************************************************************/
  999. int kr_NoOfSubPatPairs(int pattern)
  1000. {
  1001.     register int ps;
  1002.  
  1003.     if (!np_abs_count_valid)
  1004.     {
  1005.     if (kr_TotalNoOfSubPatPairs() == 0)
  1006.         return 0;
  1007.     }
  1008.  
  1009.     if (pattern<0 || 
  1010.     pattern > np_info[npui_pat_sets[npui_curr_pat_set]].number_of_pattern)
  1011.     return 0;
  1012.  
  1013.     ps = np_abs_count[pattern];
  1014.  
  1015.     if (pattern == 0)
  1016.     return ps;
  1017.     else
  1018.     return (ps - np_abs_count[pattern-1]);
  1019. }
  1020.  
  1021. /*****************************************************************************
  1022.   FUNCTION : kr_AbsPosOfFirstSubPat
  1023.  
  1024.   PURPOSE  : This function returns the absolute position of the first
  1025.   sub pattern of pattern <pattern> in the current pattern set. This
  1026.   position is defined as the Sum of kr_NoOfSubPatPairs(i) where i runs
  1027.   from 0 to <pattern>-1.  The absolute position of the first sub
  1028.   pattern of pattern 0 is 0.  The returned value may be used as
  1029.   argument for the function kr_getSubPatternByNo.
  1030.  
  1031.   RETURNS  : 
  1032.   NOTES    :
  1033.  
  1034.   UPDATE   : 
  1035. ******************************************************************************/
  1036. int kr_AbsPosOfFirstSubPat(int pattern)
  1037. {
  1038.     if (!np_abs_count_valid)
  1039.     {
  1040.     if (kr_TotalNoOfSubPatPairs() == 0)
  1041.         return 0;
  1042.     }
  1043.  
  1044.     if (pattern <= 0 || 
  1045.     pattern > np_info[npui_pat_sets[npui_curr_pat_set]].number_of_pattern)
  1046.     return 0;
  1047.  
  1048.     return np_abs_count[pattern-1];
  1049. }
  1050.  
  1051. /*****************************************************************************
  1052.   FUNCTION : kr_TotalNoOfPattern
  1053.  
  1054.   PURPOSE : This function returns the total number of available
  1055.   patterns for the current pattern set or 0 if no pattern set is
  1056.   defined.  
  1057.  
  1058.   RETURNS  : number of pattern or 0
  1059.   NOTES    :
  1060.  
  1061.   UPDATE   : 
  1062. ******************************************************************************/
  1063. int kr_TotalNoOfPattern(void)
  1064. {
  1065.     if (npui_curr_pat_set == -1)
  1066.     return 0;
  1067.  
  1068.     return np_info[npui_pat_sets[npui_curr_pat_set]].number_of_pattern;
  1069. }
  1070.  
  1071. /*****************************************************************************
  1072.   FUNCTION : kr_getSubPatData
  1073.  
  1074.   PURPOSE : For the current pattern set and the specified sub pattern
  1075.   size, the data array of the <sub_no>th sub pattern of the <pat_no>th
  1076.   pattern is returned. io_type spcifies whether the input (INPUT) or
  1077.   output (OUTPUT) data is requested. If <size> is != NULL the size of
  1078.   the data array is returned is this parameter.  
  1079.  
  1080.   RETURNS : The function returns a pointer to the data array (type
  1081.   Patterns) or NULL if an error occured.
  1082.   NOTES    : KernelErrorCode is set if an error occured
  1083.  
  1084.   UPDATE   : 
  1085. ******************************************************************************/
  1086. Patterns kr_getSubPatData(int pat_no, int sub_no, int io_type, int *size)
  1087. {
  1088.     int set;
  1089.     pattern_descriptor *pat;
  1090.     int subpos[MAX_NO_OF_VAR_DIM];
  1091.     float *data;
  1092.     krui_err err;
  1093.     static float dummy_data = 0.0;
  1094.  
  1095. #ifdef DEBUG_PATTERN
  1096.     fprintf(stderr, "pattern %d sub %d\n", pat_no, sub_no);
  1097. #endif
  1098.  
  1099.     set = npui_pat_sets[npui_curr_pat_set];
  1100.     pat = np_pat_sets[set];
  1101.     
  1102.     if (pat_no >= np_info[set].number_of_pattern)
  1103.     return (Patterns) NULL;
  1104.  
  1105.     pat += pat_no;
  1106.     np_current_pattern = pat;
  1107.     switch (io_type)
  1108.     {
  1109.       case INPUT:
  1110.     if (!kr_np_gen_sub_pos(pat->input_dim, &sub_no, pat->input_dim_sizes,
  1111.                    np_t_insize, np_t_instep, subpos, FALSE))
  1112.     {
  1113.         KernelErrorCode = KRERR_NP_NO_SUCH_PATTERN;
  1114.         return (Patterns) NULL;
  1115.     }
  1116.     if ((err = kr_np_GetSubPat(TRUE, subpos, np_t_insize, &data, size))
  1117.         != KRERR_NO_ERROR)
  1118.     {
  1119.         KernelErrorCode = err;
  1120.         return (Patterns) NULL;
  1121.     }
  1122.     return (Patterns) data;
  1123.     break;
  1124.       case OUTPUT:
  1125.     if (!kr_np_gen_sub_pos(pat->output_dim, &sub_no, pat->output_dim_sizes,
  1126.                    np_t_outsize, np_t_outstep, subpos, FALSE))
  1127.     {
  1128.         KernelErrorCode = KRERR_NP_NO_SUCH_PATTERN;
  1129.         return (Patterns) NULL;
  1130.     }
  1131.     if ((err = kr_np_GetSubPat(FALSE, subpos, np_t_outsize, &data, size))
  1132.         != KRERR_NO_ERROR)
  1133.     {
  1134.         KernelErrorCode = err;
  1135.         return (Patterns) NULL;
  1136.     }
  1137.  
  1138.     /* kr_np_GetSubPat reports no error if a zero length output sub */
  1139.     /* pattern is requested. Instead a NULL pointer is returned but */
  1140.     /* must be exchanged by a dummy non NULL pointer because this */
  1141.     /* function reports errors by NULL pointers */
  1142.     if (data == 0)
  1143.         return (Patterns) &dummy_data;
  1144.  
  1145.     return (Patterns) data;
  1146.     break;
  1147.       default:
  1148.     KernelErrorCode = KRERR_PARAMETERS;
  1149.     return (Patterns) NULL;
  1150.     }
  1151. }
  1152.  
  1153. /*****************************************************************************
  1154.   FUNCTION : kr_SizeOfInputSubPat
  1155.  
  1156.   PURPOSE  : For the current pattern set and the specified sub pattern size, 
  1157.   the size of the input part of the first sub pattern of the first pattern is 
  1158.   returned. Negative return values indicate KernelErrorCode. Size 0 is a valid 
  1159.   return value since the pattern may contain no data.
  1160.   RETURNS  : negative Kernel Error Codes or positive valid value
  1161.   NOTES    :
  1162.  
  1163.   UPDATE   : 
  1164. ******************************************************************************/
  1165. int kr_SizeOfInputSubPat(void)
  1166. {
  1167.     krui_err err;
  1168.  
  1169.     if (np_sub_pat_sizes_valid)
  1170.     return np_sub_pat_input_size;
  1171.  
  1172.     err = kr_np_GetSubPatSizes(&np_sub_pat_input_size, 
  1173.                    &np_sub_pat_output_size);
  1174.  
  1175.     if (err == KRERR_NO_ERROR)
  1176.     {
  1177.     np_sub_pat_sizes_valid = TRUE;
  1178.     return np_sub_pat_input_size;
  1179.     }
  1180.  
  1181.     return err;
  1182. }
  1183.  
  1184. /*****************************************************************************
  1185.   FUNCTION : kr_SizeOfOutputSubPat
  1186.  
  1187.   PURPOSE  : For the current pattern set and the specified sub pattern size, 
  1188.   the size of the output part of the first sub pattern of the first pattern is 
  1189.   returned. Negative return values indicate KernelErrorCode. Size 0 is a valid 
  1190.   return value since the pattern may contain no data.
  1191.   RETURNS  : negative Kernel Error Codes or positive valid value
  1192.   NOTES    :
  1193.  
  1194.   UPDATE   : 
  1195. ******************************************************************************/
  1196. int kr_SizeOfOutputSubPat(void)
  1197. {
  1198.     krui_err err;
  1199.  
  1200.     if (np_sub_pat_sizes_valid)
  1201.     return np_sub_pat_output_size;
  1202.     
  1203.     err = kr_np_GetSubPatSizes(&np_sub_pat_input_size, 
  1204.                    &np_sub_pat_output_size);
  1205.  
  1206.     if (err == KRERR_NO_ERROR)
  1207.     {
  1208.     np_sub_pat_sizes_valid = TRUE;
  1209.     return np_sub_pat_output_size;
  1210.     }
  1211.  
  1212.     return err;
  1213. }
  1214.  
  1215. /*****************************************************************************
  1216.  FUNCTIONS WHICH ARE CALLED BY THE PATTERN PARSER OR FROM INSIDE THIS
  1217.  MODULE. DON'T USE THESE FUNCTIONS FOR OTHER PURPOSES !!!!!
  1218. ******************************************************************************/
  1219.  
  1220. /*****************************************************************************
  1221.   FUNCTION : kr_np_AllocatePatternSet
  1222.  
  1223.   PURPOSE  : looks for a free slot in pattern set array and allocates <number>
  1224.              of free pattern descriptors
  1225.  
  1226.   RETURNS  : kernel error code
  1227.   NOTES    : don't call this function. This function is only to be
  1228.              called by the parser or by functions inside this module
  1229.  
  1230.   UPDATE   : 
  1231. ******************************************************************************/
  1232. krui_err kr_np_AllocatePatternSet(int *pat_set, int number)
  1233. {
  1234.     krui_err err_code;
  1235.     int i;
  1236.     int set = -1;
  1237.  
  1238.     if (np_used_pat_set_entries == 0)
  1239.     {
  1240.     /* never patterns allocated */
  1241.     err_code = kr_np_InitPattern();
  1242.     if (err_code != KRERR_NO_ERROR)
  1243.         return err_code;
  1244.     }
  1245.  
  1246.     /* check for free pattern set entry */
  1247.     for (i=0; i<np_used_pat_set_entries; i++)
  1248.     {
  1249.     if (!np_pat_set_used[i])
  1250.     {
  1251.         set = i;
  1252.         break;
  1253.     }
  1254.     }
  1255.     if (set == -1)
  1256.     {
  1257.     /* no more free entries */
  1258.     return KRERR_NP_NO_MORE_ENTRIES;
  1259.     }
  1260.  
  1261.     /* allocate array of pattern descriptors */
  1262.     np_pat_sets[set] = 
  1263.     (pattern_descriptor *) malloc(number * sizeof(pattern_descriptor));
  1264.     if (np_pat_sets[set] == (pattern_descriptor *) NULL && number != 0)
  1265.     return KRERR_INSUFFICIENT_MEM;
  1266.  
  1267.     /* initialize part of the pattern descriptors */
  1268.     for (i=0; i<number; i++)
  1269.     {
  1270.     np_pat_sets[set][i].input_fixsize = 0;
  1271.     np_pat_sets[set][i].output_fixsize = 0;
  1272.     np_pat_sets[set][i].input_pattern = (float *) NULL;
  1273.     np_pat_sets[set][i].output_pattern = (float *) NULL;
  1274.     np_pat_sets[set][i].input_info = (char *) NULL;
  1275.     np_pat_sets[set][i].output_info = (char *) NULL;
  1276.     }
  1277.  
  1278.     /* store number of allocated descriptors */
  1279.     np_info[set].number_of_pattern = number;
  1280.     np_info_valid[set] = FALSE; /* only number_of_pattern is valid */
  1281.  
  1282.     /* sucessfull return */
  1283.     np_pat_set_used[set] = TRUE;
  1284.     *pat_set = set;
  1285.     return KRERR_NO_ERROR;
  1286. }
  1287.  
  1288. /*****************************************************************************
  1289.   FUNCTION : kr_np_AllocatePattern
  1290.  
  1291.   PURPOSE  : uses the information provided in given pattern descriptor to
  1292.              allocate memory for pattern data
  1293.  
  1294.   RETURNS  : kernel error code
  1295.   NOTES    : don't call this function. This function is only to be
  1296.              called by the parser or by functions inside this module
  1297.  
  1298.   UPDATE   : 
  1299. ******************************************************************************/
  1300. krui_err kr_np_AllocatePattern(pattern_descriptor *pattern,
  1301.                    bool input)
  1302. {
  1303.     int i;
  1304.     int size;
  1305.  
  1306.     if (np_used_pat_set_entries == 0)
  1307.     return KRERR_NO_PATTERNS;
  1308.  
  1309.     if (input)
  1310.     {
  1311.     size = pattern -> input_fixsize;
  1312.     for (i=0; i<pattern -> input_dim; i++)
  1313.         size *= (pattern -> input_dim_sizes)[i];
  1314.     pattern -> input_info = (char *) NULL;
  1315.     pattern -> input_pattern = (float *) malloc(size * sizeof(float));
  1316.     if (pattern -> input_pattern == (float *) NULL && size != 0)
  1317.         return KRERR_INSUFFICIENT_MEM;
  1318.     else
  1319.         return KRERR_NO_ERROR;
  1320.     }
  1321.     else
  1322.     {
  1323.     size = pattern -> output_fixsize;
  1324.     for (i=0; i<pattern -> output_dim; i++)
  1325.         size *= (pattern -> output_dim_sizes)[i];
  1326.     pattern -> output_info = (char *) NULL;
  1327.     pattern -> output_pattern = (float *) malloc(size * sizeof(float));
  1328.     if (pattern -> output_pattern == (float *) NULL && size != 0)
  1329.         return KRERR_INSUFFICIENT_MEM;
  1330.     else
  1331.         return KRERR_NO_ERROR;
  1332.     }
  1333. }
  1334.  
  1335. /*****************************************************************************
  1336.   FUNCTION : kr_np_GetDescriptor
  1337.  
  1338.   PURPOSE  : determine a pointer to a specified pattern descriptor
  1339.              and make this pattern to be the current pattern
  1340.  
  1341.   RETURNS  : kernel error code
  1342.   NOTES    : don't call this function. This function is only to be
  1343.              called by the parser or by functions inside this module
  1344.  
  1345.   UPDATE   : 
  1346. ******************************************************************************/
  1347. krui_err kr_np_GetDescriptor(int pat_set, int number, 
  1348.                  pattern_descriptor **pattern)
  1349. {
  1350.     if (np_used_pat_set_entries == 0)
  1351.     return KRERR_NO_PATTERNS;
  1352.  
  1353.     if (pat_set < 0 || pat_set >= np_used_pat_set_entries ||
  1354.     !np_pat_set_used[pat_set])
  1355.     return KRERR_NP_NO_SUCH_PATTERN_SET;
  1356.  
  1357.     if (number >= np_info[pat_set].number_of_pattern)
  1358.     return KRERR_PATTERN_NO;
  1359.  
  1360.     *pattern = np_current_pattern = &(np_pat_sets[pat_set][number]);
  1361.  
  1362.     return KRERR_NO_ERROR;
  1363. }
  1364.  
  1365. /*****************************************************************************
  1366.  INTERNAL FUNCTIONS OF THIS MODULE. IMPOSSIBLE TO CALL THESE FUNCTIONS
  1367.  FROM OUTSIDE THE MODULE (IF NOBODY CHANGES THE STATIC DECLARATION) !!!!!!!
  1368. ******************************************************************************/
  1369.  
  1370. /*****************************************************************************
  1371.   FUNCTION : kr_np_InitPattern
  1372.  
  1373.   PURPOSE  : initialization of pattern descriptor array
  1374.   RETURNS  : kernel error code
  1375.   NOTES    : internal use only
  1376.  
  1377.   UPDATE   : 
  1378. ******************************************************************************/
  1379. static krui_err kr_np_InitPattern(void)
  1380. {
  1381.     int i;
  1382.  
  1383.     np_pat_sets = (pattern_descriptor **) malloc(NO_OF_PAT_SETS *
  1384.                          sizeof(pattern_descriptor *));
  1385.     np_pat_set_used = (bool *) malloc(NO_OF_PAT_SETS * sizeof(bool));
  1386.     np_info = (pattern_set_info *) malloc(NO_OF_PAT_SETS *
  1387.                      sizeof(pattern_set_info));
  1388.  
  1389.     np_info_valid = (bool *) malloc(NO_OF_PAT_SETS * sizeof(bool));
  1390.  
  1391.     if (np_pat_sets == (pattern_descriptor **) NULL ||
  1392.     np_info == (pattern_set_info *) NULL ||
  1393.     np_info_valid == (bool *) NULL)
  1394.     {
  1395.     return KRERR_INSUFFICIENT_MEM;
  1396.     }
  1397.     else
  1398.     {
  1399.     np_used_pat_set_entries = NO_OF_PAT_SETS;
  1400.     for (i=0; i<NO_OF_PAT_SETS; i++)
  1401.     {
  1402.         np_pat_sets[i] = (pattern_descriptor *) NULL;
  1403.         np_pat_set_used[i] = FALSE;
  1404.         np_info_valid[i] = FALSE;
  1405.     }
  1406.  
  1407.     return KRERR_NO_ERROR;
  1408.     }
  1409. }
  1410.  
  1411.  
  1412. /*****************************************************************************
  1413.   FUNCTION : kr_np_ReallocatePatternSet
  1414.  
  1415.   PURPOSE  : reallocates the pattern set <pat_set> to contain <new_number> 
  1416.              of pattern entries.
  1417.  
  1418.   RETURNS  : kernel error code
  1419.   NOTES    : internal use only
  1420.  
  1421.   UPDATE   : 
  1422. ******************************************************************************/
  1423. static krui_err kr_np_ReallocatePatternSet(int pat_set, int new_number)
  1424. {
  1425.     pattern_descriptor *new_mem;
  1426.  
  1427.     /* check whether patterns are allocated */
  1428.     if (np_used_pat_set_entries == 0)
  1429.     return KRERR_NP_NO_SUCH_PATTERN_SET;
  1430.  
  1431.     /* check whether the pattern set is present */
  1432.     if (!np_pat_set_used[pat_set])
  1433.     return KRERR_NP_NO_SUCH_PATTERN_SET;
  1434.  
  1435.     /* reallocate array of pattern descriptors */
  1436.     if (np_pat_sets[pat_set] != (pattern_descriptor *) NULL)
  1437.     {
  1438.     new_mem = (pattern_descriptor *) 
  1439.         realloc(np_pat_sets[pat_set],
  1440.             new_number * sizeof(pattern_descriptor));
  1441.     }
  1442.     else
  1443.     {
  1444.     new_mem = (pattern_descriptor *) 
  1445.         malloc(new_number * sizeof(pattern_descriptor));
  1446.     }
  1447.  
  1448.     if (new_mem == (pattern_descriptor *) NULL && new_number != 0)
  1449.     return KRERR_INSUFFICIENT_MEM;
  1450.  
  1451.     np_pat_sets[pat_set] = new_mem;
  1452.  
  1453.     /* store number of allocated descriptors */
  1454.     np_info[pat_set].number_of_pattern = new_number;
  1455.     np_info_valid[pat_set] = FALSE; /* only number_of_pattern is valid */
  1456.  
  1457.     /* sucessfull return */
  1458.     return KRERR_NO_ERROR;
  1459. }
  1460.  
  1461. /*****************************************************************************
  1462.   FUNCTION : kr_np_DeletePatternSet
  1463.  
  1464.   PURPOSE  : delete a pattern set and free all memory
  1465.   RETURNS  : kernel error code
  1466.   NOTES    : internal use only
  1467.  
  1468.   UPDATE   : 
  1469. ******************************************************************************/
  1470. static krui_err kr_np_DeletePatternSet(int pat_set)
  1471. {
  1472.     int i;
  1473.     pattern_descriptor *p;
  1474.  
  1475.     /* check for valid number of pattern set */
  1476.     if (np_used_pat_set_entries == 0)
  1477.     return KRERR_NO_PATTERNS;
  1478.  
  1479.     if (pat_set<0 || pat_set>=np_used_pat_set_entries)
  1480.     return KRERR_NP_NO_SUCH_PATTERN_SET;
  1481.     
  1482.     p = np_pat_sets[pat_set];
  1483.     if (!np_pat_set_used[pat_set])
  1484.     return KRERR_NP_NO_SUCH_PATTERN_SET;
  1485.  
  1486.     /* free all pattern */
  1487.     for (i=0; i<np_info[pat_set].number_of_pattern; i++)
  1488.     {
  1489.     if (p -> input_pattern != (float *) NULL)
  1490.         free(p -> input_pattern);
  1491.     if (p -> input_info != (char *) NULL)
  1492.         free(p -> input_info);
  1493.     if (p -> output_pattern != (float *) NULL)
  1494.         free(p -> output_pattern);
  1495.     if (p -> output_info != (char *) NULL)
  1496.         free(p -> output_info);
  1497.     p++;
  1498.     }
  1499.  
  1500.     /* free the pattern descriptors */ 
  1501.     if (np_pat_sets[pat_set] != (pattern_descriptor *) NULL)
  1502.     free(np_pat_sets[pat_set]);
  1503.     np_pat_sets[pat_set] = (pattern_descriptor *) NULL;
  1504.     np_pat_set_used[pat_set] = FALSE;
  1505.  
  1506.     np_info[pat_set].number_of_pattern = 0;
  1507.     np_info_valid[pat_set] = FALSE;
  1508.     np_current_pattern = (pattern_descriptor *) NULL;
  1509.  
  1510.     return KRERR_NO_ERROR;
  1511. }
  1512.  
  1513. /*****************************************************************************
  1514.   FUNCTION : kr_np_DeletePattern
  1515.  
  1516.   PURPOSE  : delete a specific pattern form a pattern set
  1517.   RETURNS  : kernel error code
  1518.   NOTES    : internal use only
  1519.  
  1520.   UPDATE   : 
  1521. ******************************************************************************/
  1522. static krui_err kr_np_DeletePattern(int pat_set, int pattern)
  1523. {
  1524.     pattern_descriptor *p;
  1525.     int i;
  1526.  
  1527.     /* check for valid number of pattern set */
  1528.     if (np_used_pat_set_entries == 0)
  1529.     return KRERR_NO_PATTERNS;
  1530.  
  1531.     if (pat_set<0 || pat_set>=np_used_pat_set_entries)
  1532.     return KRERR_NP_NO_SUCH_PATTERN_SET;
  1533.     
  1534.     p = np_pat_sets[pat_set];
  1535.     if (!np_pat_set_used[pat_set])
  1536.     return KRERR_NP_NO_SUCH_PATTERN_SET;
  1537.  
  1538.     if (pattern < 0 || pattern >= np_info[pat_set].number_of_pattern)
  1539.     return KRERR_NP_NO_SUCH_PATTERN;
  1540.  
  1541.     /* free memory for the specified pattern */
  1542.     p += pattern;
  1543.     if (p -> input_pattern != (float *) NULL)
  1544.     free(p -> input_pattern);
  1545.     if (p -> input_info != (char *) NULL)
  1546.     free(p -> input_info);
  1547.     if (p -> output_pattern != (float *) NULL)
  1548.     free(p -> output_pattern);
  1549.     if (p -> output_info != (char *) NULL)
  1550.     free(p -> output_info);
  1551.  
  1552.     /* move tail of array one position to fill up the empty entry */
  1553.     for (i=pattern+1; i<np_info[pat_set].number_of_pattern; i++)
  1554.     {
  1555.     (void) memcpy((char *) p, (char *) (p+1), sizeof(pattern_descriptor));
  1556.     p++;
  1557.     }
  1558.  
  1559.     /* last entry of the array is no longer active */
  1560.     return kr_np_ReallocatePatternSet(pat_set, 
  1561.                    np_info[pat_set].number_of_pattern-1);
  1562. }
  1563.  
  1564. /*****************************************************************************
  1565.   FUNCTION : kr_np_AddPattern
  1566.  
  1567.   PURPOSE  : Add an empty pattern descriptor to the specified pattern set. 
  1568.              The position of the pattern inside the set is returned 
  1569.              in <pattern>.
  1570.   RETURNS  : kernel error code
  1571.   NOTES    : internal use only
  1572.  
  1573.   UPDATE   : 
  1574. ******************************************************************************/
  1575. static krui_err kr_np_AddPattern(int pat_set, int *pattern)
  1576. {
  1577.     krui_err err;
  1578.     pattern_descriptor *p;
  1579.     int number;
  1580.  
  1581.     /* check for valid number of pattern set */
  1582.     if (np_used_pat_set_entries == 0)
  1583.     return KRERR_NO_PATTERNS;
  1584.  
  1585.     if (pat_set<0 || pat_set>=np_used_pat_set_entries)
  1586.     return KRERR_NP_NO_SUCH_PATTERN_SET;
  1587.     
  1588.     p = np_pat_sets[pat_set];
  1589.     if (!np_pat_set_used[pat_set])
  1590.     return KRERR_NP_NO_SUCH_PATTERN_SET;
  1591.  
  1592.     number = np_info[pat_set].number_of_pattern + 1;
  1593.     err = kr_np_ReallocatePatternSet(pat_set, number);
  1594.  
  1595.     if (err != KRERR_NO_ERROR)
  1596.     return err;
  1597.  
  1598.     p = np_pat_sets[pat_set];
  1599.     p += (number-1);
  1600.  
  1601.     /* initialize part of the new pattern descriptors */
  1602.     {
  1603.     p -> input_fixsize = 0;
  1604.     p -> output_fixsize = 0;
  1605.     p -> input_dim = 0;
  1606.     p -> output_dim = 0;
  1607.     p -> input_pattern = (float *) NULL;
  1608.     p -> output_pattern = (float *) NULL;
  1609.     }
  1610.  
  1611.     *pattern = (number-1);
  1612.     return KRERR_NO_ERROR;
  1613. }
  1614.  
  1615. /*****************************************************************************
  1616.   FUNCTION : kr_np_LoadPatternFile
  1617.  
  1618.   PURPOSE  : loads new or old pattern file from pat_file. The number of the 
  1619.              associated pattern set is returned in pat_set.
  1620.   RETURNS  : kernel error code
  1621.   NOTES    : internal use only
  1622.  
  1623.   UPDATE   : 
  1624. ******************************************************************************/
  1625. static krui_err kr_np_LoadPatternFile(FILE *pat_file, int *pat_set)
  1626. {
  1627.     int i;
  1628.     bool free;
  1629.     krui_err err_code;
  1630.     int pattern_set;
  1631.  
  1632.     /* be sure to have a place where to put the patterns */
  1633.     if (np_used_pat_set_entries == 0)
  1634.     {
  1635.     /* never patterns allocated */
  1636.     err_code = kr_np_InitPattern();
  1637.     if (err_code != KRERR_NO_ERROR)
  1638.         return err_code;
  1639.     }
  1640.     else
  1641.     {
  1642.     free = FALSE;
  1643.  
  1644.     /* check for free entry before starting parser */
  1645.     for (i=0; i<np_used_pat_set_entries; i++)
  1646.     {
  1647.         if (!np_pat_set_used[i])
  1648.         {
  1649.         free = TRUE;
  1650.         break;
  1651.         }
  1652.     }
  1653.  
  1654.     if (!free)
  1655.         return KRERR_NP_NO_MORE_ENTRIES;        
  1656.     }
  1657.  
  1658.     /* reset the scanner and the parser */
  1659.     scanner_init_scanner(pat_file);
  1660.  
  1661.     /* parse pattern file and check for errors */
  1662.     if (parse_pattern_file(&pattern_set) != 0)
  1663.     {
  1664.     (void) kr_np_DeletePatternSet(pattern_set);
  1665.     return KRERR_FILE_FORMAT;
  1666.     }
  1667.     else
  1668.     {
  1669.     *pat_set = pattern_set;
  1670.     return KRERR_NO_ERROR;
  1671.     }
  1672. }
  1673.  
  1674. /*****************************************************************************
  1675.   FUNCTION : kr_np_SavePatternFile
  1676.  
  1677.   PURPOSE  : save the pattern set pat_set to out_file
  1678.   RETURNS  : kernel error code
  1679.   NOTES    : internal use only
  1680.  
  1681.   UPDATE   : 
  1682. ******************************************************************************/
  1683. static krui_err kr_np_SavePatternFile(FILE *out_file, int pat_set)
  1684. {
  1685.     pattern_set_info info;
  1686.     krui_err err_code;
  1687.     int i, j, n;
  1688.     float *in_pat, *out_pat;
  1689.     time_t clock;
  1690.     
  1691.     if (np_used_pat_set_entries == 0)
  1692.     return KRERR_NO_PATTERNS;
  1693.  
  1694.     if (pat_set<0 || pat_set>=np_used_pat_set_entries)
  1695.     return KRERR_NP_NO_SUCH_PATTERN_SET;
  1696.     
  1697.     if (!np_pat_set_used[pat_set])
  1698.     return KRERR_NP_NO_SUCH_PATTERN_SET;
  1699.  
  1700.     err_code = kr_np_GetInfo(pat_set, &info);
  1701.     if (err_code != KRERR_NO_ERROR)
  1702.     return err_code;
  1703.  
  1704.     if (info.number_of_pattern == 0)
  1705.     return KRERR_NO_PATTERNS;
  1706.  
  1707.     fprintf(out_file, "SNNS pattern definition file V%d.%d\n",
  1708.         CURRENT_VERSION_V, CURRENT_VERSION_R);
  1709.     clock = time((time_t *) NULL);
  1710.     fprintf(out_file, "generated at %s\n\n", (char *) ctime(&clock));
  1711.     fprintf(out_file, "No. of patterns : %d\n", info.number_of_pattern);
  1712.     fprintf(out_file, "No. of input units : %d\n", info.in_fixsize);
  1713.     if (info.out_fixsize != 0)
  1714.     fprintf(out_file, "No. of output units : %d\n", info.out_fixsize);
  1715.     if (info.in_number_of_dims != 0)
  1716.     {
  1717.     fprintf(out_file, "No. of variable input dimensions : %d\n", 
  1718.         info.in_number_of_dims);
  1719.     fprintf(out_file, "Maximum input dimensions : [ ");
  1720.     for (i=0; i<info.in_number_of_dims; i++)
  1721.     {
  1722.         fprintf(out_file, "%d ", info.in_max_dim_sizes[i]);
  1723.     }
  1724.     fprintf(out_file, "]\n");
  1725.     }
  1726.     if (info.out_fixsize != 0 && info.out_number_of_dims != 0)
  1727.     {
  1728.     fprintf(out_file, "No. of variable output dimensions : %d\n", 
  1729.         info.out_number_of_dims);
  1730.     fprintf(out_file, "Maximum output dimensions : [ ");
  1731.     for (i=0; i<info.out_number_of_dims; i++)
  1732.     {
  1733.         fprintf(out_file, "%d ", info.out_max_dim_sizes[i]);
  1734.     }
  1735.     fprintf(out_file, "]\n");
  1736.     }
  1737.     fprintf(out_file, "\n");
  1738.  
  1739.     for (j=0; j<info.number_of_pattern; j++)
  1740.     {
  1741.     if (np_pat_sets[pat_set][j].input_fixsize > 0)
  1742.     {
  1743.         fprintf(out_file, "# Input pattern %d:\n", j+1);
  1744.         n = info.in_fixsize;
  1745.         if (info.in_number_of_dims != 0)
  1746.         {
  1747.         fprintf(out_file, "[ ");
  1748.         for (i=0; i<np_pat_sets[pat_set][j].input_dim; i++)
  1749.         {
  1750.             fprintf(out_file, "%d ", 
  1751.                 np_pat_sets[pat_set][j].input_dim_sizes[i]);
  1752.             n *= np_pat_sets[pat_set][j].input_dim_sizes[i];
  1753.         }
  1754.         fprintf(out_file, "]\n");
  1755.         }
  1756.         in_pat = np_pat_sets[pat_set][j].input_pattern;
  1757.         for (i=0; i<n; i++)
  1758.         {
  1759.         fprintf(out_file, "%g ", *in_pat++);
  1760.         if (i == n - 1 || i%10 == 9)
  1761.             fprintf(out_file, "\n");
  1762.         }
  1763.     }
  1764.  
  1765.     if (np_pat_sets[pat_set][j].output_fixsize > 0)
  1766.     {
  1767.         fprintf(out_file, "# Output pattern %d:\n", j+1);
  1768.         n = info.out_fixsize;
  1769.         if (info.out_number_of_dims != 0)
  1770.         {
  1771.         fprintf(out_file, "[ ");
  1772.         for (i=0; i<np_pat_sets[pat_set][j].output_dim; i++)
  1773.         {
  1774.             fprintf(out_file, "%d ", 
  1775.                 np_pat_sets[pat_set][j].output_dim_sizes[i]);
  1776.             n *= np_pat_sets[pat_set][j].output_dim_sizes[i];
  1777.         }
  1778.         fprintf(out_file, "]\n");
  1779.         }
  1780.         out_pat = np_pat_sets[pat_set][j].output_pattern;
  1781.         for (i=0; i<n; i++)
  1782.         {
  1783.         fprintf(out_file, "%g ", *out_pat++);
  1784.         if (i == n - 1 || i%10 == 9)
  1785.             fprintf(out_file, "\n");
  1786.         }
  1787.     }
  1788.     }
  1789.  
  1790.     return KRERR_NO_ERROR;
  1791. }
  1792.  
  1793. /*****************************************************************************
  1794.   FUNCTION : kr_np_GetInfo
  1795.  
  1796.   PURPOSE  : get some information about the specified pattern set
  1797.   RETURNS  : kernel error code
  1798.   NOTES    : internal use only
  1799.  
  1800.   UPDATE   : 
  1801. ******************************************************************************/
  1802. static krui_err kr_np_GetInfo(int pat_set, pattern_set_info *info)
  1803. {
  1804.     int i, j;
  1805.     pattern_descriptor *p;
  1806.     
  1807.  
  1808.     if (np_used_pat_set_entries == 0)
  1809.     return KRERR_NO_PATTERNS;
  1810.  
  1811.     if (pat_set < 0 || pat_set >= np_used_pat_set_entries ||
  1812.     !np_pat_set_used[pat_set])
  1813.     return KRERR_NP_NO_SUCH_PATTERN_SET;
  1814.  
  1815.     if (np_info_valid[pat_set])
  1816.     {
  1817.     *info = np_info[pat_set];
  1818.     return KRERR_NO_ERROR;
  1819.     }
  1820.  
  1821.     p = np_pat_sets[pat_set];
  1822.     info -> number_of_pattern = np_info[pat_set].number_of_pattern;
  1823.     info -> fixed_fixsizes = TRUE;
  1824.  
  1825.     if (info -> number_of_pattern > 0 && p != (pattern_descriptor *) NULL)
  1826.     {
  1827.     info -> output_present = p-> output_fixsize != 0;
  1828.     info -> in_fixsize = p -> input_fixsize;
  1829.     info -> out_fixsize = p-> output_fixsize;
  1830.     info -> in_number_of_dims = p->input_dim;
  1831.     info -> out_number_of_dims = p->output_dim;
  1832.  
  1833.     for (j=0; j < p->input_dim; j++)
  1834.     {
  1835.         (info -> in_max_dim_sizes)[j] = (info -> in_min_dim_sizes)[j] =
  1836.         (p -> input_dim_sizes)[j];
  1837.     }
  1838.     for (j=0; j < p->output_dim; j++)
  1839.     {
  1840.         (info -> out_max_dim_sizes)[j] = (info -> out_min_dim_sizes)[j] =
  1841.         (p -> output_dim_sizes)[j];
  1842.     }
  1843.     }
  1844.     
  1845.     for (i=0; i<info -> number_of_pattern; i++)
  1846.     {
  1847.     if (p -> input_fixsize != info -> in_fixsize)
  1848.     {
  1849.         info -> fixed_fixsizes = FALSE;
  1850.         info -> in_fixsize = -1;
  1851.     }
  1852.     if (p -> output_fixsize != info -> out_fixsize)
  1853.     {
  1854.         info -> fixed_fixsizes = FALSE;
  1855.         info -> out_fixsize = -1;
  1856.     }
  1857.  
  1858.     for (j=0; j < p->input_dim; j++)
  1859.     {
  1860.         if ((p -> input_dim_sizes)[j] > (info -> in_max_dim_sizes)[j])
  1861.         (info -> in_max_dim_sizes)[j] = p -> input_dim_sizes[j];
  1862.         if ((p -> input_dim_sizes)[j] < (info -> in_min_dim_sizes)[j])
  1863.         (info -> in_min_dim_sizes)[j] = p -> input_dim_sizes[j];
  1864.     }
  1865.     for (j=0; j < p->output_dim; j++)
  1866.     {
  1867.         if ((p -> output_dim_sizes)[j] > (info -> out_max_dim_sizes)[j])
  1868.         (info -> out_max_dim_sizes)[j] = p -> output_dim_sizes[j];
  1869.         if ((p -> output_dim_sizes)[j] < (info -> out_min_dim_sizes)[j])
  1870.         (info -> out_min_dim_sizes)[j] = p -> output_dim_sizes[j];
  1871.     }
  1872.     
  1873.     p++;
  1874.     }
  1875.  
  1876.     np_info[pat_set] = *info;
  1877.     np_info_valid[pat_set] = TRUE;
  1878.  
  1879.     return KRERR_NO_ERROR;
  1880. }
  1881.  
  1882. /*****************************************************************************
  1883.   FUNCTION : kr_np_GetSubPatSizes
  1884.  
  1885.   PURPOSE  : Depending on the current pattern set and the sub pattern 
  1886.   training scheme, which must be defined, the size of the first input sub 
  1887.   pattern and the size of the first output sub pattern is computed.
  1888.   RETURNS  : kernel error code
  1889.   NOTES    : internal use only
  1890.  
  1891.   UPDATE   : 
  1892. ******************************************************************************/
  1893. static krui_err kr_np_GetSubPatSizes(int *input_size, int *output_size)
  1894. {
  1895.     int pat_set;
  1896.     pattern_descriptor *pattern;
  1897.     int i;
  1898.  
  1899.     if (!npui_train_defined)
  1900.     return KRERR_NP_NO_TRAIN_SCHEME;
  1901.  
  1902.     pat_set = npui_pat_sets[npui_curr_pat_set];
  1903.     pattern = &(np_pat_sets[pat_set][0]);
  1904.  
  1905.     *input_size = pattern -> input_fixsize;
  1906.     for (i=0; i<pattern -> input_dim; i++)
  1907.     {
  1908.     *input_size *= np_t_insize[i];
  1909.     }
  1910.  
  1911.     *output_size = pattern -> output_fixsize;
  1912.     for (i=0; i<pattern -> output_dim; i++)
  1913.     {
  1914.     *output_size *= np_t_outsize[i];
  1915.     }
  1916.  
  1917.     return KRERR_NO_ERROR;
  1918. }
  1919.  
  1920. /*****************************************************************************
  1921.   FUNCTION : kr_np_GetSubPat
  1922.  
  1923.   PURPOSE  : copy a sub pattern into another area 
  1924.  
  1925. A sub pattern is cut out of the current pattern at position
  1926. <pos_coord> with size <size_coord>. According to <input> the input
  1927. part or the output part of the current pattern is used. A pointer to
  1928. an array of float which contains the cut part is returned in <data>.
  1929. <pos_coord> is an array of int which defines the position of the sub
  1930. pattern inside the variable sized dimensions of the pattern.
  1931. <size_coord> is an array of int which defines the size of the sub
  1932. pattern in each dimensional direction. Both arrays must contain
  1933. <input_dim> (or <output_dim>) entries (see pattern descriptor).
  1934.  
  1935. Example: pattern with input_fixsize 2, input_dim 2, input_dim_sizes [4 5]
  1936. (hint: the values of the pattern represent the position)
  1937.  
  1938. {
  1939. 0.00, 0.01, 0.10, 0.11, 0.20, 0.21, 0.30, 0.31, 0.40, 0.41,
  1940. 1.00, 1.01, 1.10, 1.11, 1.20, 1.21, 1.30, 1.31, 1.40, 1.41,
  1941. 2.00, 2.01, 2.10, 2.11, 2.20, 2.21, 2.30, 2.31, 2.40, 2.41,
  1942. 3.00, 3.01, 3.10, 3.11, 3.20, 3.21, 3.30, 3.31, 3.40, 3.41,
  1943. }
  1944.  
  1945. the sub pattern with <pos_coord> [1 2], <size_coord> [3 2] looks like
  1946. this:
  1947.  
  1948. {
  1949. 1.20, 1.21, 1.30, 1.31,
  1950. 2.20, 2.21, 2.30, 2.31,
  1951. 3.20, 3.21, 3.30, 3.31,
  1952. }
  1953.  
  1954. The parameter entries returns the number of entries in the data field.
  1955.  
  1956.   RETURNS  : kernel error code
  1957.   NOTES    : internal use only
  1958.  
  1959.   UPDATE   : 
  1960. ******************************************************************************/
  1961. static krui_err kr_np_GetSubPat(bool input, int *pos_coord, int *size_coord,
  1962.                 float **data, int *entries)
  1963. {
  1964.     int u_dim;                   /* copy of all necessary variables from */
  1965.     int u_size;                  /* pattern descriptor, depending on */
  1966.     int *u_dim_sizes;            /* <input> */
  1967.     float *u_pattern;
  1968.     int npu_subpatsize;
  1969.     float *npu_subpat;
  1970.  
  1971.     int f_size;                  /* size of copy area */
  1972.     int i;
  1973.     int c[MAX_NO_OF_VAR_DIM];    /* counter for the dimensions */
  1974.     int copy_size;               /* size of copy block for each memcpy */
  1975.     float *cf;                   /* pointer into pattern (copy source) */
  1976.     float *cdest;                /* copy destination */
  1977.     bool stop;                   /* TRUE if all done */
  1978.     int offset;                  /* offset in multidimensional array */
  1979.  
  1980.     /* check for valid pattern */
  1981.     if (np_used_pat_set_entries == 0)
  1982.     return KRERR_NO_PATTERNS;
  1983.  
  1984.     if (np_current_pattern == (pattern_descriptor *) NULL)
  1985.     return KRERR_NP_NO_CURRENT_PATTERN;
  1986.  
  1987.     /* make a copy of all pattern info to work with */
  1988.     if (input)
  1989.     {
  1990.     u_dim = np_current_pattern -> input_dim;
  1991.     u_size = np_current_pattern -> input_fixsize;
  1992.     u_dim_sizes = np_current_pattern -> input_dim_sizes;
  1993.     u_pattern = np_current_pattern -> input_pattern;
  1994.     npu_subpatsize = np_i_subpatsize;
  1995.     npu_subpat = np_i_subpat;
  1996.     }
  1997.     else
  1998.     {
  1999.     u_dim = np_current_pattern -> output_dim;
  2000.     u_size = np_current_pattern -> output_fixsize;
  2001.     u_dim_sizes = np_current_pattern -> output_dim_sizes;
  2002.     u_pattern = np_current_pattern -> output_pattern;
  2003.     npu_subpatsize = np_o_subpatsize;
  2004.     npu_subpat = np_o_subpat;
  2005.     }
  2006.  
  2007.     /* check whether this pattern exists */
  2008.     if (u_size == 0)
  2009.     {
  2010.     if (input)
  2011.         return KRERR_NP_NO_SUCH_PATTERN;
  2012.     else
  2013.     {
  2014.         /* this may be a network without output neurons, so don't */
  2015.         /* produce an error but set the data pointer to NULL */
  2016.  
  2017.         *data = (float *) NULL;
  2018.         if (entries != (int *) NULL)
  2019.         *entries = 0;
  2020.         return KRERR_NO_ERROR;
  2021.     }
  2022.     }
  2023.  
  2024.     /* calculate size of the sub pattern and check dimensions */
  2025.     f_size = u_size;
  2026.     for (i=0; i<u_dim; i++)
  2027.     {
  2028.     f_size *= size_coord[i];
  2029.     if (pos_coord[i] + size_coord[i] > u_dim_sizes[i])
  2030.         return KRERR_NP_DIMENSION;
  2031.     c[i] = 0;
  2032.     }
  2033.  
  2034.     /* allocate space for sub pattern if necessary */
  2035.     if (f_size > npu_subpatsize)
  2036.     {
  2037.     if (npu_subpat != (float *) NULL)
  2038.         free(npu_subpat);
  2039.     npu_subpat = (float *) malloc(f_size * sizeof(float));
  2040.     if (npu_subpat == (float *) NULL && f_size != 0)
  2041.     {
  2042.         return KRERR_INSUFFICIENT_MEM;
  2043.     }
  2044.     npu_subpatsize = f_size;
  2045.  
  2046.     /* copy back new address and size */
  2047.     if (input)
  2048.     {
  2049.         np_i_subpatsize = npu_subpatsize;
  2050.         np_i_subpat = npu_subpat;
  2051.     }
  2052.     else
  2053.     {
  2054.         np_o_subpatsize = npu_subpatsize;
  2055.         np_o_subpat = npu_subpat;
  2056.     }
  2057.     }
  2058.  
  2059.  
  2060.     /* calculate size of one copy block. this includes the size of the */
  2061.     /* dimension with highest index (least significant dimension) */
  2062.     copy_size = u_size;
  2063.     if (u_dim>0)
  2064.     copy_size *= size_coord[u_dim-1];
  2065.  
  2066.     /* copy the sub pattern */
  2067.     cdest = npu_subpat;
  2068.     do
  2069.     {
  2070.     /* calculate offset in source pattern */
  2071.     offset = 0;
  2072.     for (i=0; i<u_dim; i++)
  2073.     {
  2074.         offset *= u_dim_sizes[i];
  2075.         offset += pos_coord[i] + c[i];
  2076.     }
  2077.     offset *= u_size;
  2078.     cf = u_pattern + offset;
  2079.  
  2080.     /* copy part of the pattern. this inlcudes the least significant */
  2081.     /* dimension */
  2082.     (void) memcpy((char *) cdest, (char *) cf, copy_size * sizeof(float));
  2083.     cdest += copy_size;
  2084.  
  2085.     /* count the dimensions and check whether we have to go on. */
  2086.     /* the least significant dimension is omitted, because it is already */
  2087.     /* copied */
  2088.     stop = TRUE;
  2089.     for (i=u_dim-2; i>=0; i--)
  2090.     {
  2091.         c[i]++;
  2092.         if (c[i] == size_coord[i])
  2093.         c[i] = 0;
  2094.         else
  2095.         {
  2096.         stop = FALSE;
  2097.         break;
  2098.         }
  2099.     }
  2100.     } while (!stop);
  2101.  
  2102.     /* all done, return results */
  2103.     *data = npu_subpat;
  2104.     if (entries != (int *) NULL)
  2105.     *entries = f_size;
  2106.     return KRERR_NO_ERROR;
  2107. }
  2108.  
  2109. /*****************************************************************************
  2110.   FUNCTION : kr_np_SetSubPat
  2111.  
  2112.   PURPOSE  : copy another area into a sub pattern
  2113.  
  2114. A sub pattern is cut out of the current pattern at position
  2115. <pos_coord> with size <size_coord>. According to <input> the input
  2116. part or the output part of the current pattern is used. 
  2117. <pos_coord> is an array of int which defines the position of the sub
  2118. pattern inside the variable sized dimensions of the pattern.
  2119. <size_coord> is an array of int which defines the size of the sub
  2120. pattern in each dimensional direction. Both arrays must contain
  2121. <input_dim> (or <output_dim>) entries (see pattern descriptor).
  2122.  
  2123. Example: pattern with input_fixsize 2, input_dim 2, input_dim_sizes [4 5]
  2124. (hint: the values of the pattern represent the position)
  2125.  
  2126. {
  2127. 0.00, 0.01, 0.10, 0.11, 0.20, 0.21, 0.30, 0.31, 0.40, 0.41,
  2128. 1.00, 1.01, 1.10, 1.11, 1.20, 1.21, 1.30, 1.31, 1.40, 1.41,
  2129. 2.00, 2.01, 2.10, 2.11, 2.20, 2.21, 2.30, 2.31, 2.40, 2.41,
  2130. 3.00, 3.01, 3.10, 3.11, 3.20, 3.21, 3.30, 3.31, 3.40, 3.41,
  2131. }
  2132.  
  2133. the sub pattern with <pos_coord> [1 2], <size_coord> [3 2] looks like
  2134. this:
  2135.  
  2136. {
  2137. 1.20, 1.21, 1.30, 1.31,
  2138. 2.20, 2.21, 2.30, 2.31,
  2139. 3.20, 3.21, 3.30, 3.31,
  2140. }
  2141.  
  2142. The parameter entries returns the number of entries in the data field.
  2143.  
  2144.   RETURNS  : kernel error code
  2145.   NOTES    : internal use only
  2146.  
  2147.   UPDATE   : 
  2148. ******************************************************************************/
  2149. static krui_err kr_np_SetSubPat(bool input, int *pos_coord, int *size_coord,
  2150.                 float *data, int entries)
  2151. {
  2152.     int u_dim;                   /* copy of all necessary variables from */
  2153.     int u_size;                  /* pattern descriptor, depending on */
  2154.     int *u_dim_sizes;            /* <input> */
  2155.     float *u_pattern;
  2156.  
  2157.     int f_size;                  /* size of copy area */
  2158.     int i;
  2159.     int c[MAX_NO_OF_VAR_DIM];    /* counter for the dimensions */
  2160.     int copy_size;               /* size of copy block for each memcpy */
  2161.     float *cf;                   /* pointer into pattern (copy destination) */
  2162.     float *csource;              /* copy source */
  2163.     bool stop;                   /* TRUE if all done */
  2164.     int offset;                  /* offset in multidimensional array */
  2165.  
  2166.     /* check for valid pattern */
  2167.     if (np_used_pat_set_entries == 0)
  2168.     return KRERR_NO_PATTERNS;
  2169.  
  2170.     if (np_current_pattern == (pattern_descriptor *) NULL)
  2171.     return KRERR_NP_NO_CURRENT_PATTERN;
  2172.  
  2173.     /* make a copy of all pattern info to work with */
  2174.     if (input)
  2175.     {
  2176.     u_dim = np_current_pattern -> input_dim;
  2177.     u_size = np_current_pattern -> input_fixsize;
  2178.     u_dim_sizes = np_current_pattern -> input_dim_sizes;
  2179.     u_pattern = np_current_pattern -> input_pattern;
  2180.     }
  2181.     else
  2182.     {
  2183.     u_dim = np_current_pattern -> output_dim;
  2184.     u_size = np_current_pattern -> output_fixsize;
  2185.     u_dim_sizes = np_current_pattern -> output_dim_sizes;
  2186.     u_pattern = np_current_pattern -> output_pattern;
  2187.     }
  2188.  
  2189.     /* check whether this pattern exists or whether all is done */
  2190.     if (u_size == 0)
  2191.     {
  2192.     if (entries == 0)
  2193.         return KRERR_NO_ERROR;
  2194.     else
  2195.         return KRERR_NP_NO_SUCH_PATTERN;
  2196.     }
  2197.  
  2198.     /* calculate size of the sub pattern and check dimensions */
  2199.     f_size = u_size;
  2200.     for (i=0; i<u_dim; i++)
  2201.     {
  2202.     f_size *= size_coord[i];
  2203.     if (pos_coord[i] + size_coord[i] > u_dim_sizes[i])
  2204.         return KRERR_NP_DIMENSION;
  2205.     c[i] = 0;
  2206.     }
  2207.  
  2208.     /* check whether calculated space fits the delievered data block */
  2209.     if (f_size != entries)
  2210.     return KRERR_NP_DOES_NOT_FIT;
  2211.  
  2212.     /* calculate size of one copy block. this includes the size of the */
  2213.     /* dimension with highest index (least significant dimension) */
  2214.     copy_size = u_size;
  2215.     if (u_dim>0)
  2216.     copy_size *= size_coord[u_dim-1];
  2217.  
  2218.     /* copy the sub pattern */
  2219.     csource = data;
  2220.     do
  2221.     {
  2222.     /* calculate offset in destination pattern */
  2223.     offset = 0;
  2224.     for (i=0; i<u_dim; i++)
  2225.     {
  2226.         offset *= u_dim_sizes[i];
  2227.         offset += pos_coord[i] + c[i];
  2228.     }
  2229.     offset *= u_size;
  2230.     cf = u_pattern + offset;
  2231.  
  2232.     /* copy part of the pattern. this inlcudes the least significant */
  2233.     /* dimension */
  2234.     (void) memcpy((char *) cf, (char *)csource, copy_size * sizeof(float));
  2235.     csource += copy_size;
  2236.  
  2237.     /* count the dimensions and check whether we have to go on. */
  2238.     /* the least significant dimension is omitted, because it is already */
  2239.     /* copied */
  2240.     stop = TRUE;
  2241.     for (i=u_dim-2; i>=0; i--)
  2242.     {
  2243.         c[i]++;
  2244.         if (c[i] == size_coord[i])
  2245.         c[i] = 0;
  2246.         else
  2247.         {
  2248.         stop = FALSE;
  2249.         break;
  2250.         }
  2251.     }
  2252.     } while (!stop);
  2253.  
  2254.     /* all done, return results */
  2255.     return KRERR_NO_ERROR;
  2256. }
  2257.  
  2258. /*****************************************************************************
  2259.   FUNCTION : kr_np_align_sub_pos
  2260.  
  2261.   PURPOSE  : For a given pattern dimension size <psize> of <dim>
  2262.              dimensions and a given sub pattern size <ssize> the position
  2263.          <spos> of the sub pattern is alligned to a valid position
  2264.          and the ordering number of this sub pattern is returned
  2265.          in <n>. The shift pattern given in <sstep> is used to
  2266.          find valid allignment positions
  2267.  
  2268.   RETURNS  : TRUE if succesfull, FALSE if inconsistent parameters
  2269.  
  2270.              <n> starts with 0 and ends with <number of possible
  2271.          positions> - 1
  2272.          <spos> gives the new aligned position
  2273.  
  2274.   NOTES    : internal function
  2275.  
  2276.   UPDATE   : 
  2277. ******************************************************************************/
  2278. static bool kr_np_align_sub_pos(int dim, int *n, int *psize, int *ssize, 
  2279.                 int *sstep, int *spos)
  2280. {
  2281.     int ns[MAX_NO_OF_VAR_DIM];
  2282.     register int i;
  2283.     register int ts = 0;
  2284.  
  2285.     for (i=0; i<dim; i++)
  2286.     {
  2287.     /* calculate how much steps could be made in each dimension */
  2288.     ns[i] = (psize[i] - ssize[i] + sstep[i]) / sstep[i];
  2289.     if (ns[i] == 0)
  2290.         return FALSE;
  2291.  
  2292.     /* align the position of this dimension */
  2293.     spos[i] -= spos[i] % sstep[i];
  2294.     if (spos[i]+ssize[i] >= psize[i]+1)
  2295.         spos[i] = 0;
  2296.  
  2297.     /* add the position of this dimension to the absolute position */
  2298.     ts *= ns[i];
  2299.     ts += spos[i]/sstep[i];
  2300.     }
  2301.  
  2302.     *n = ts;
  2303.     return TRUE;
  2304. }
  2305.  
  2306. /*****************************************************************************
  2307.   FUNCTION : kr_np_gen_sub_pos
  2308.  
  2309.   PURPOSE  : For a given pattern dimension size <psize> of <dim>
  2310.              dimensions and a given sub pattern size <ssize> the position
  2311.          <spos> of the <n>th sub pattern is calculated. The shift
  2312.          pattern given in <sstep> is used to move sub pattern over
  2313.          the pattern.
  2314.  
  2315.          If <count> is TRUE, only the number of possible positions
  2316.          is determined and returned in <n> if at least 1 valid
  2317.          position exists. <spos> is of no effect and may be NULL.
  2318.  
  2319.   RETURNS  : TRUE if the <n>th subpattern exists or if <count> is TRUE
  2320.              and at least 1 valid position exists, FALSE if <n> < 0.
  2321.          If <n> is higher than the available number of subpattern, a 
  2322.          wraparound occurs.
  2323.  
  2324.              <n> starts with 0 and ends with <number of possible
  2325.          positions> - 1 or returns number of possible positions.
  2326.  
  2327.   NOTES    : internal function
  2328.  
  2329.   UPDATE   : 
  2330. ******************************************************************************/
  2331. static bool kr_np_gen_sub_pos(int dim, int *n, int *psize, int *ssize, 
  2332.                   int *sstep, int *spos, bool count)
  2333. {
  2334.     int ns[MAX_NO_OF_VAR_DIM];
  2335.     int i;
  2336.     int ts;
  2337.     int nn;
  2338.  
  2339.     nn = *n;
  2340.  
  2341.     /* calculate how much steps could be made in each dimension */
  2342.     /* and the total number of positions ts (define the bases of a */
  2343.     /* multi base numerative system and determine the highest */
  2344.     /* representable number) */
  2345.     ts = 1;
  2346.     for (i=dim-1; i>=0; i--)
  2347.     {
  2348.     ns[i] = (psize[i] - ssize[i] + sstep[i]) / sstep[i];
  2349.     if (ns[i] == 0)
  2350.         return FALSE;
  2351.     ts *= ns[i];
  2352.     }
  2353.  
  2354.     /* check whether this is all what we want to do now */
  2355.     if (count)
  2356.     {
  2357.     *n = ts;
  2358.     return TRUE;
  2359.     }
  2360.     
  2361.     /* check range of requested step position */ 
  2362.     if (nn<0)
  2363.     return FALSE;
  2364.  
  2365.     /* if requested position is higher than available positions, perform */
  2366.     /* wraparaound (this is usefull/necessary for pattern without subpattern */
  2367.     nn = nn%ts;
  2368.  
  2369.     /* calculate step position of the <n>th sub pattern (like counting */
  2370.     /* in a multi base numerative system) */
  2371.     for (i=dim-1; i>=0; i--)
  2372.     {
  2373.     spos[i] = (nn % ns[i]) * sstep[i];
  2374.     nn /= ns[i];
  2375.     }
  2376.     
  2377.     return TRUE;
  2378. }
  2379.  
  2380. /*****************************************************************************
  2381.   FUNCTION : kr_np_allocate_pat_train_entries
  2382.  
  2383.   PURPOSE  : allocate or reallocate an array which will later include
  2384.              the sorted or shuffled pattern order (during training)
  2385.   RETURNS  : FALSE if malloc fails
  2386.   NOTES    : internal use only
  2387.  
  2388.   UPDATE   : 
  2389. ******************************************************************************/
  2390. static bool kr_np_allocate_pat_train_entries(int n)
  2391. {
  2392.     if (n > np_pat_train_size)
  2393.     {
  2394.     if (np_pat_train_order != (int *) NULL)
  2395.         free(np_pat_train_order);
  2396.     np_pat_train_size = 0;
  2397.     np_pat_train_order = (int *) malloc(n * sizeof(int));
  2398.     if (np_pat_train_order == (int *) NULL && n != 0)
  2399.         return FALSE;
  2400.     np_pat_train_size = n;
  2401.     np_pat_train_valid = FALSE;
  2402.     }
  2403.     return TRUE;
  2404. }
  2405.  
  2406. /*****************************************************************************
  2407.   FUNCTION : kr_np_allocate_sub_pat_train_entries
  2408.  
  2409.   PURPOSE  : allocate or reallocate an array which will later include
  2410.              the sorted or shuffled order of the sub pattern of the
  2411.          current pattern
  2412.   RETURNS  : FALSE if malloc fails
  2413.   NOTES    : internal use only
  2414.  
  2415.   UPDATE   : 
  2416. ******************************************************************************/
  2417. static bool kr_np_allocate_sub_pat_train_entries(int n)
  2418. {
  2419.     if (n > np_sub_pat_train_size)
  2420.     {
  2421.     if (np_sub_pat_train_order != (int *) NULL)
  2422.         free(np_sub_pat_train_order);
  2423.     np_sub_pat_train_size = 0;
  2424.     np_sub_pat_train_order = (int *) malloc(n * sizeof(int));
  2425.     if (np_sub_pat_train_order == (int *) NULL && n != 0)
  2426.         return FALSE;
  2427.     np_sub_pat_train_size = n;
  2428.     np_sub_pat_train_valid = FALSE;
  2429.     }
  2430.     return TRUE;
  2431. }
  2432.  
  2433. /*****************************************************************************
  2434.   FUNCTION : kr_np_order_pat_entries
  2435.  
  2436.   PURPOSE  : Fills the allocated array for the pattern ordering with
  2437.              increasing numbers if patterns are sorted or with a
  2438.          random permutation if patterns are shuffled.
  2439.          <start> and <end> define the first and last pattern
  2440.          number to be used
  2441.   RETURNS  : nothing
  2442.   NOTES    : internal use only
  2443.  
  2444.   UPDATE   : 
  2445. ******************************************************************************/
  2446. static void kr_np_order_pat_entries(int start, int end)
  2447. {
  2448.     static bool shuffle;
  2449.     static int c_start;
  2450.     static int c_end;
  2451.  
  2452.     register int i;
  2453.     register int *fp;
  2454.     register int h;
  2455.     register int s;
  2456.     register int n;
  2457.  
  2458.     if (!np_pat_train_valid || c_start != start || c_end != end 
  2459.     || shuffle != npui_shuffle_pattern)
  2460.     {
  2461.     fp = np_pat_train_order;
  2462.     for (i=start; i<=end; i++)
  2463.         *fp++ = i;
  2464.     np_pat_train_valid = TRUE;
  2465.     np_pat_train_number = end - start + 1;
  2466.     c_start = start;
  2467.     c_end = end;
  2468.     shuffle = npui_shuffle_pattern;
  2469.     }
  2470.  
  2471.     if (shuffle)
  2472.     {
  2473.     n = np_pat_train_number;
  2474.     fp = np_pat_train_order;
  2475.     for (i=0; i<n; i++)
  2476.     {
  2477.         s = lrand48() % (n-i);
  2478.         h = *fp;
  2479.         *fp++ = np_pat_train_order[s+i];
  2480.         np_pat_train_order[s+i] = h;
  2481.     }
  2482.     }
  2483. }
  2484.  
  2485. /*****************************************************************************
  2486.   FUNCTION : kr_np_order_sub_pat_entries
  2487.  
  2488.   PURPOSE  : Fills the allocated array for the sub pattern ordering with
  2489.              increasing numbers if sub patterns are sorted or with a
  2490.          random permutation if sub patterns are shuffled.
  2491.          <start> and <end> define the first and last sub pattern
  2492.          number to be used
  2493.   RETURNS  : nothing
  2494.   NOTES    : internal use only
  2495.  
  2496.   UPDATE   : 
  2497. ******************************************************************************/
  2498. static void kr_np_order_sub_pat_entries(int start, int end)
  2499. {
  2500.     static bool shuffle;
  2501.     static int c_start;
  2502.     static int c_end;
  2503.  
  2504.     register int i;
  2505.     register int *fp;
  2506.     register int h;
  2507.     register int s;
  2508.     register int n;
  2509.  
  2510.     if (!np_sub_pat_train_valid || c_start != start || c_end != end 
  2511.     || shuffle != npui_shuffle_sub_pattern)
  2512.     {
  2513.     fp = np_sub_pat_train_order;
  2514.     for (i=start; i<=end; i++)
  2515.         *fp++ = i;
  2516.     np_sub_pat_train_valid = TRUE;
  2517.     np_sub_pat_train_number = end - start + 1;
  2518.     c_start = start;
  2519.     c_end = end;
  2520.     shuffle = npui_shuffle_sub_pattern;
  2521.     }
  2522.  
  2523.     if (shuffle)
  2524.     {
  2525.     n = np_sub_pat_train_number;
  2526.     fp = np_sub_pat_train_order;
  2527.     for (i=0; i<n; i++)
  2528.     {
  2529.         s = lrand48() % (n-i);
  2530.         h = *fp;
  2531.         *fp++ = np_sub_pat_train_order[s+i];
  2532.         np_sub_pat_train_order[s+i] = h;
  2533.     }
  2534.     }
  2535. }
  2536.  
  2537. /*****************************************************************************
  2538.   FUNCTION : kr_np_DefineSubPatternOrdering
  2539.  
  2540.   PURPOSE : definition of generation of sub pattern during training
  2541.  
  2542.   The shape and ordering of sub patterns for training and display is
  2543.   defined.  <pat_set> specifies the pattern set to use. The flag
  2544.   <input> determines whether input or output sub patterns are to be
  2545.   defined. The array size_coord spezifies the shape of the sub pattern
  2546.   like in kr_np_GetSubPat. The array incr_coord specifies how sub
  2547.   patterns are generated from the whole pattern by shifting the shape
  2548.   over this pattern. Each value in this array gives an incremental
  2549.   offset for one dimensional direction. The start position is at [0 0
  2550.   0 ...]. New positions are generated by adding the rightmost value of
  2551.   incr_coord to the old position. If an overflow in this dimension
  2552.   occurs, this coordinate is reset to 0 and the next position to the
  2553.   left is incremented (and so on ...). After all sub patterns of one
  2554.   pattern are generated the next pattern is used.  Depending on
  2555.   npui_shuffle_pattern and npui_shuffle_sub_pattern shuffling is
  2556.   activated.
  2557.  
  2558.   RETURNS  : kernel error code
  2559.   NOTES    : internal use only
  2560.  
  2561.   UPDATE   : 
  2562. ******************************************************************************/
  2563. static krui_err kr_np_DefineSubPatternOrdering(int pat_set, bool input, 
  2564.                            int *size_coord, 
  2565.                            int *incr_coord)
  2566. {
  2567.     krui_err err_code;
  2568.     pattern_descriptor *p;
  2569.  
  2570.     if (np_used_pat_set_entries == 0)
  2571.     return KRERR_NO_PATTERNS;
  2572.  
  2573.     if (pat_set < 0 || pat_set >= np_used_pat_set_entries ||
  2574.     !np_pat_set_used[pat_set])
  2575.     return KRERR_NP_NO_SUCH_PATTERN_SET;
  2576.  
  2577.     err_code = kr_np_GetDescriptor(pat_set, 0, &p);
  2578.     if (err_code != KRERR_NO_ERROR)
  2579.     return err_code;
  2580.  
  2581.     if (input)
  2582.     {
  2583.     memcpy((char *) np_t_insize, (char *) size_coord, 
  2584.            p->input_dim * sizeof(int));
  2585.     memcpy((char *) np_t_instep, (char *) incr_coord, 
  2586.            p->input_dim * sizeof(int));
  2587.     }
  2588.     else
  2589.     {
  2590.     memcpy((char *) np_t_outsize, (char *) size_coord, 
  2591.            p->input_dim * sizeof(int));
  2592.     memcpy((char *) np_t_outstep, (char *) incr_coord, 
  2593.            p->input_dim * sizeof(int));
  2594.     }
  2595.  
  2596.     np_pat_train_valid = FALSE;
  2597.     np_sub_pat_train_valid = FALSE;
  2598.  
  2599.     return KRERR_NO_ERROR;
  2600. }
  2601.  
  2602. /*****************************************************************************
  2603.   FUNCTION : kr_np_showPatternSTD
  2604.  
  2605.   PURPOSE  :  According to the mode kr_np_showPatternSTD stores the current
  2606.               Pattern/sub Pattern into the units activation (and/or output) 
  2607.           values.
  2608.               The modes are:
  2609.               - OUTPUT_NOTHING
  2610.               store input pattern into input units activations
  2611.               - OUTPUT_ACT
  2612.               store input pattern into input units activations and
  2613.               store output pattern into output units activations
  2614.               - OUTPUT_OUT
  2615.               store input pattern into input units activations,
  2616.               store output pattern into output units activations and
  2617.               update output units output
  2618.   RETURNS  :  kernel error code
  2619.   NOTES    :  See include file glob_typ.h for mode constants.
  2620.               internal use only
  2621.   UPDATE   : 
  2622. ******************************************************************************/
  2623. static krui_err kr_np_showPatternSTD(int mode)
  2624. {
  2625.     register struct Unit *unit_ptr;
  2626.     float *in_pat, *out_pat;
  2627.     pattern_descriptor *pattern;
  2628.     int in_pat_size, out_pat_size;
  2629.  
  2630.     /* make the pattern to become the current pattern */ 
  2631.     if ((KernelErrorCode = 
  2632.      kr_np_GetDescriptor(npui_pat_sets[npui_curr_pat_set],
  2633.                  npui_curr_pattern-1, &pattern)) 
  2634.     != KRERR_NO_ERROR)
  2635.     return KernelErrorCode;
  2636.   
  2637.     /*  calc. startaddress of patterns  */
  2638.     if ((KernelErrorCode = 
  2639.      kr_np_GetSubPat(TRUE, npui_inpos, npui_insize, &in_pat, 
  2640.              &in_pat_size)) 
  2641.     != KRERR_NO_ERROR)
  2642.     return KernelErrorCode;
  2643.  
  2644.     if ((KernelErrorCode = 
  2645.      kr_np_GetSubPat(FALSE, npui_outpos, npui_outsize, &out_pat, 
  2646.              &out_pat_size)) 
  2647.     != KRERR_NO_ERROR)
  2648.     return KernelErrorCode;
  2649.  
  2650.     /* calculate the units, ignore error code concerning old pattern format */
  2651.     (void) kr_IOCheck();
  2652.     KernelErrorCode = KRERR_NO_ERROR;
  2653.  
  2654.     /* check whether pattern fits the network, do not complain about */
  2655.     /* missing output pattern */
  2656.     if (NoOfInputUnits != in_pat_size ||
  2657.     (NoOfOutputUnits != out_pat_size && out_pat_size != 0))
  2658.     return KernelErrorCode = KRERR_NP_DOES_NOT_FIT;
  2659.  
  2660.     switch (mode)
  2661.     {
  2662.       case  OUTPUT_NOTHING:
  2663.     FOR_ALL_UNITS( unit_ptr )
  2664.         if ( IS_INPUT_UNIT( unit_ptr ) && UNIT_IN_USE( unit_ptr ))
  2665.         if (in_pat_size--)
  2666.             unit_ptr->act = *in_pat++;
  2667.     break;
  2668.  
  2669.       case  OUTPUT_ACT:
  2670.     FOR_ALL_UNITS( unit_ptr )
  2671.         if UNIT_IN_USE( unit_ptr )
  2672.         {
  2673.         if IS_INPUT_UNIT( unit_ptr )
  2674.             unit_ptr->act = *in_pat++;
  2675.         if (IS_OUTPUT_UNIT( unit_ptr ) && out_pat_size != 0)
  2676.             unit_ptr->act = *out_pat++;
  2677.         }
  2678.     break;
  2679.  
  2680.       case  OUTPUT_OUT:
  2681.     FOR_ALL_UNITS( unit_ptr )
  2682.         if UNIT_IN_USE( unit_ptr )
  2683.         {
  2684.         if IS_INPUT_UNIT( unit_ptr )
  2685.             unit_ptr->act = *in_pat++;
  2686.         if (IS_OUTPUT_UNIT( unit_ptr ) && out_pat_size != 0)
  2687.         {
  2688.             unit_ptr->act = *out_pat++;
  2689.             if (unit_ptr->out_func == NULL)
  2690.             /*  Identity Function   */
  2691.             unit_ptr->Out.output = unit_ptr->act;
  2692.             else
  2693.             unit_ptr->Out.output = 
  2694.                 (*unit_ptr->out_func) (unit_ptr->act);
  2695.         }
  2696.         }
  2697.     break;
  2698.     
  2699.       default:
  2700.     KernelErrorCode = KRERR_PARAMETERS;
  2701.     }
  2702.  
  2703.     return( KernelErrorCode );
  2704. }
  2705.  
  2706. /*****************************************************************************
  2707.   FUNCTION : kr_np_modifyPattern
  2708.  
  2709.   PURPOSE  : The current activation of the input and output units is used to
  2710.              modify the current sub pattern.
  2711.  
  2712.   RETURNS  : kernel error code
  2713.   NOTES    : internal use only
  2714.   UPDATE   : 
  2715. ******************************************************************************/
  2716. static krui_err kr_np_modifyPattern(void)
  2717. {
  2718.     register struct Unit *unit_ptr;
  2719.     float *in_pat, *out_pat;
  2720.     float *ip, *op;
  2721.     pattern_descriptor *pattern;
  2722.  
  2723.     /* make the pattern to become the current pattern */ 
  2724.     if ((KernelErrorCode = 
  2725.      kr_np_GetDescriptor(npui_pat_sets[npui_curr_pat_set],
  2726.                  npui_curr_pattern-1, &pattern)) 
  2727.     != KRERR_NO_ERROR)
  2728.     return KernelErrorCode;
  2729.   
  2730.     /* calculate the units, ignore error code concerning old pattern format */
  2731.     (void) kr_IOCheck();
  2732.     KernelErrorCode = KRERR_NO_ERROR;
  2733.  
  2734.     /* allocate memory to hold the sub pattern */
  2735.     in_pat = (float *) malloc(NoOfInputUnits * sizeof(float));
  2736.     out_pat = (float *) malloc(NoOfOutputUnits * sizeof(float));
  2737.     if ((in_pat == (float *) NULL && NoOfInputUnits != 0) 
  2738.     || (out_pat == (float *) NULL && NoOfOutputUnits != 0))
  2739.     return KRERR_INSUFFICIENT_MEM;
  2740.  
  2741.     /* copy unit activations into sub pattern area */
  2742.     ip = in_pat;
  2743.     op = out_pat;
  2744.  
  2745.     FOR_ALL_UNITS(unit_ptr)
  2746.         if (UNIT_IN_USE(unit_ptr))
  2747.     {
  2748.         if (IS_INPUT_UNIT(unit_ptr))
  2749.         *ip++ = unit_ptr->act;
  2750.         if (IS_OUTPUT_UNIT(unit_ptr))
  2751.         *op++ =  unit_ptr->act;
  2752.         }
  2753.  
  2754.     KernelErrorCode = KRERR_NO_ERROR;
  2755.  
  2756.     /* test whether pattern already contains data. */
  2757.     /* allocate space if necessary (for new allocated patterns) */
  2758.     if (pattern -> input_fixsize == 0)
  2759.     {
  2760.     pattern -> input_fixsize = NoOfInputUnits;
  2761.     pattern -> output_fixsize = NoOfOutputUnits;
  2762.     pattern -> input_dim = 0;
  2763.     pattern -> output_dim = 0;
  2764.     KernelErrorCode = kr_np_AllocatePattern(pattern, TRUE);
  2765.     if (KernelErrorCode == KRERR_NO_ERROR)
  2766.         KernelErrorCode = kr_np_AllocatePattern(pattern, FALSE);
  2767.     }
  2768.  
  2769.     /* modify the copied sub pattern */
  2770.     if (KernelErrorCode == KRERR_NO_ERROR)
  2771.     {
  2772.     KernelErrorCode = kr_np_SetSubPat(TRUE, npui_inpos, npui_insize,
  2773.                       in_pat, NoOfInputUnits);
  2774.     }
  2775.  
  2776.     if (KernelErrorCode == KRERR_NO_ERROR)
  2777.     {
  2778.     KernelErrorCode = kr_np_SetSubPat(FALSE, npui_outpos, npui_outsize,
  2779.                       out_pat, NoOfOutputUnits);
  2780.     }
  2781.  
  2782.     /* free the memory */
  2783.     if (in_pat != (float *) NULL)
  2784.     free(in_pat);
  2785.     if (out_pat != (float *) NULL)
  2786.     free(out_pat);
  2787.  
  2788.     return KernelErrorCode;
  2789. }
  2790.  
  2791. /*****************************************************************************
  2792. END OF FILE
  2793. ******************************************************************************/
  2794.